【Unity】AssetBundle —— 单例类管理

一个简单的AssetBundle的单例类,单例类是Unity单例类,这意味着这个单例类会在世界中存在,但由于设置了HideFlags,因此不会在大纲中看到

这个管理类基本是在提供的原生API的基础上,附加了一些功能,包括

        修改加载路径,宏判断平台名称

        使用泛型方式输入包名和资产名进行资源加载,支持同步和异步

        使用字典缓存AB包,防止重复加载

        缓存主包和主包的manifest,对外使用属性的方式只读获取

单例类

public class UnitySingleton<T> : MonoBehaviour where T : Component
{
    private static T _instance;

    public static T Instance
    {
        get
        {
            if(_instance == null)
            {
                _instance = FindObjectOfType(typeof(T)) as T;
                if( _instance == null)
                {
                    GameObject obj = new GameObject();
                    _instance = (T)obj.AddComponent(typeof(T));
                    obj.hideFlags = HideFlags.HideAndDontSave;
                    obj.name = typeof(T).Name;
                }
            }
            return _instance;
        }
    }

    protected virtual void Awake()
    {
        DontDestroyOnLoad(this.gameObject);
        if (_instance == null)
            _instance = this as T;
        else
            GameObject.Destroy(this.gameObject);
    }
}

AB包管理类

public class ABMgr : UnitySingleton<ABMgr>
{
    //同步加载
    public T Load<T>(string abName, string assetName) where T : Object
    {
        abName += ".u3d";

        //加载依赖包
        string[] dependencies = manifest.GetAllDependencies(abName);
        foreach (string dependency in dependencies)
        {
            if(!_abDic.ContainsKey(dependency))
                _abDic.Add(dependency, AssetBundle.LoadFromFile(abURL + dependency));
        }

        //加载所需包
        if(!_abDic.ContainsKey(abName))
            _abDic.Add(abName, AssetBundle.LoadFromFile(abURL + abName));

        //返回对象
        return _abDic[abName].LoadAsset<T>(assetName);
    }

    //异步加载
    public void LoadAsync<T>(string abName, string assetName, UnityAction<T> callback) where T : Object
    {
        StartCoroutine(LoadAsyncCoroutine(abName, assetName, callback));
    }
    private IEnumerator LoadAsyncCoroutine<T>(string abName, string assetName, UnityAction<T> callback) where T : Object
    {
        abName += ".u3d";

        //加载依赖包
        string[] dependencies = manifest.GetAllDependencies(abName);
        foreach (string dependency in dependencies)
        {
            if(!_abDic.ContainsKey(dependency))
            {
                AssetBundleCreateRequest req = AssetBundle.LoadFromFileAsync(abURL + dependency);
                yield return req;
                _abDic.Add(dependency, req.assetBundle);
            }
        }

        //加载所需包
        if(!_abDic.ContainsKey(abName))
        {
            AssetBundleCreateRequest req = AssetBundle.LoadFromFileAsync(abURL + abName);
            yield return req;
            _abDic.Add(abName, req.assetBundle);
        }

        //异步加载,触发回调
        AssetBundleRequest asset = _abDic[abName].LoadAssetAsync(assetName);
        yield return asset;
        callback(asset.asset as T);
    }

    //单个卸载
    public void Unload(string abName)
    {
        if(_abDic.ContainsKey(abName))
        {
            _abDic[abName].Unload(false);
            _abDic.Remove(abName);
        }
    }

    //全部卸载
    public void UnloadAll()
    {
        AssetBundle.UnloadAllAssetBundles(false);
        _abDic.Clear();
        _mainAB = null;
        _manifest = null;
    }


    private void OnApplicationQuit()
    {
        UnloadAll();
    }


    //平台名称
    public string platform {
        get {
#if UNTIY_IOS
            return "IOS";
#elif UNITY_ANDROID
            return "Androids";
#elif UNITY_STANDALONE
            return "StandaloneWindows";
#endif
        }
    }

    //AB包路径
    public string abURL => Application.streamingAssetsPath + "/";

    //缓存加载过的AB包
    private Dictionary<string, AssetBundle> _abDic = new Dictionary<string, AssetBundle>();

    //全局主包和全局依赖表
    private AssetBundle _mainAB = null;
    private AssetBundleManifest _manifest = null;
    public AssetBundle mainAB {
        get { 
            if(_mainAB == null)
                _mainAB = AssetBundle.LoadFromFile(abURL + platform);
            return _mainAB;
        }
    }
    public AssetBundleManifest manifest {
        get {
            if(_manifest == null)
                _manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
            return _manifest;
        }
    }
}

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值