当前位置: 首页 > article >正文

Unity 简单使用Addressables加载SpriteAtlas图集资源

 思路很简单,传入图集名和资源名,利用Addressables提供的异步加载方式从ab包中加载。加载完成后存储进缓存字典里,以供后续使用。

添加引用计数,防止多个地方使用同一图集时,不会提前释放

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.U2D.SpriteAtlas;
using System.Collections.Generic;

public class SpriteAtlasManager : MonoBehaviour
{
    // 单例实例
    private static SpriteAtlasManager _instance;
    public static SpriteAtlasManager Instance
    {
        get
        {
            if (_instance == null)
            {
                GameObject go = new GameObject("SpriteAtlasManager");
                _instance = go.AddComponent<SpriteAtlasManager>();
                DontDestroyOnLoad(go);
            }
            return _instance;
        }
    }

    // 图集缓存字典
    private Dictionary<string, AtlasCacheInfo> _atlasCache = 
        new Dictionary<string, AtlasCacheInfo>();

    /// <summary>
    /// 加载Sprite
    /// </summary>
    /// <param name="atlasName">图集的Addressable名称</param>
    /// <param name="spriteName">Sprite在图集中的名称</param>
    /// <param name="onComplete">加载完成回调</param>
    public void LoadSprite(string atlasName, string spriteName, 
        System.Action<Sprite> onComplete)
    {
        // 如果图集已加载
        if (_atlasCache.TryGetValue(atlasName, out AtlasCacheInfo cacheInfo))
        {
            // 直接获取Sprite
            Sprite sprite = cacheInfo.Atlas.GetSprite(spriteName);
            if (sprite != null)
            {
                cacheInfo.RefCount++; // 增加引用计数
                onComplete?.Invoke(sprite);
            }
            else
            {
                Debug.LogError($"图集 {atlasName} 中找不到Sprite: {spriteName}");
                onComplete?.Invoke(null);
            }
            return;
        }

        // 异步加载图集
        AsyncOperationHandle<SpriteAtlas> handle = 
            Addressables.LoadAssetAsync<SpriteAtlas>(atlasName);

        handle.Completed += op =>
        {
            if (op.Status == AsyncOperationStatus.Succeeded)
            {
                // 缓存图集
                var newCache = new AtlasCacheInfo
                {
                    Handle = handle,
                    Atlas = op.Result,
                    RefCount = 1
                };
                _atlasCache.Add(atlasName, newCache);

                // 获取Sprite
                Sprite sprite = newCache.Atlas.GetSprite(spriteName);
                if (sprite != null)
                {
                    onComplete?.Invoke(sprite);
                }
                else
                {
                    Debug.LogError($"图集 {atlasName} 中找不到Sprite: {spriteName}");
                    Addressables.Release(handle); // 立即释放
                    _atlasCache.Remove(atlasName);
                    onComplete?.Invoke(null);
                }
            }
            else
            {
                Debug.LogError($"图集 {atlasName} 加载失败");
                onComplete?.Invoke(null);
            }
        };
    }

    /// <summary>
    /// 释放Sprite
    /// </summary>
    /// <param name="atlasName">图集的Addressable名称</param>
    public void UnloadSprite(string atlasName)
    {
        if (_atlasCache.TryGetValue(atlasName, out AtlasCacheInfo cacheInfo))
        {
            cacheInfo.RefCount--;
            if (cacheInfo.RefCount <= 0)
            {
                Addressables.Release(cacheInfo.Handle);
                _atlasCache.Remove(atlasName);
            }
        }
    }

    // 图集缓存信息
    private class AtlasCacheInfo
    {
        public AsyncOperationHandle<SpriteAtlas> Handle;
        public SpriteAtlas Atlas;
        public int RefCount; // 引用计数
    }

    void OnDestroy()
    {
        // 清理所有缓存
        foreach (var pair in _atlasCache)
        {
            Addressables.Release(pair.Value.Handle);
        }
        _atlasCache.Clear();
    }
}

使用例: 

// 在需要加载Sprite的地方调用
SpriteAtlasManager.Instance.LoadSprite("UI_Atlas", "hero_icon", sprite =>
{
    if (sprite != null)
    {
        GetComponent<Image>().sprite = sprite;
    }
});

// 当不再需要时释放
SpriteAtlasManager.Instance.UnloadSprite("UI_Atlas");


http://www.kler.cn/a/613545.html

相关文章:

  • java使用aspose添加多个图片到word
  • 3.27-1 pymysql下载及使用
  • Stable Diffusion 基础模型结构超级详解!
  • 用 pytorch 从零开始创建大语言模型(七):根据指示进行微调
  • TextGrad:案例
  • 横扫SQL面试——事件流处理(峰值统计)问题
  • SDL —— 将sdl渲染画面嵌入Qt窗口显示(附:源码)
  • CSS回顾-Flex弹性盒布局
  • Vue $bus被多次触发
  • 【WPF】ListView数据绑定
  • 【AI工具开发】Notepad++插件开发实践:从基础交互到ScintillaCall集成
  • C语言之链表
  • 分布式光伏防逆流如何实现?
  • 每日免费分享之精品wordpress主题系列~DAY16
  • 云原生四重涅槃·破镜篇:混沌工程证道心,九阳真火锻金身
  • 可视化图解算法:递归基础
  • Pyside6介绍和开发第一个程序
  • GPT4o漫画制作(小白教程)
  • 后端开发中的文件上传的实现
  • Amazon CodeWhisperer 挑战十大排序算法