2023-06-08 Unity AssetBundle2——AB包资源管理器AssetBundleMgr

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Object = UnityEngine.Object;

public class AssetBundleMgr : MonoBehaviour
{
    
    
    /// <summary>
    /// AB 包存放路径
    /// </summary>
    private static readonly string AB_DIRECTORY = Application.streamingAssetsPath + "/";

    /// <summary>
    /// 主包名
    /// </summary>
    private static readonly string MAIN_AB_NAME = "StandaloneWindows";

    /// <summary>
    /// 主包
    /// </summary>
    private AssetBundle mainAB = null;

    /// <summary>
    /// 依赖包获取用的配置文件
    /// </summary>
    private AssetBundleManifest manifest = null;

    /// <summary>
    /// 存储加载过的 AB 包,避免重复加载报错
    /// </summary>
    private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();

    public static AssetBundleMgr Instance {
    
     get; private set; }

    protected virtual void Awake() {
    
    
        if (Instance == null) {
    
    
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
    }

    /// <summary>
    /// 同步加载 AB 包
    /// </summary>
    /// <param name="abName"></param>
    public void LoadAB(string abName) {
    
    
        // 加载主包
        if (mainAB == null) {
    
    
            mainAB   = AssetBundle.LoadFromFile(AB_DIRECTORY + MAIN_AB_NAME);
            manifest = mainAB.LoadAsset<AssetBundleManifest>(nameof(AssetBundleManifest));
        }

        // 获取依赖包相关信息
        string[] strs = manifest.GetAllDependencies(abName);
        for (int i = 0; i < strs.Length; i++) {
    
    
            if (!abDic.ContainsKey(strs[i])) {
    
    
                AssetBundle temp = AssetBundle.LoadFromFile(AB_DIRECTORY + strs[i]);
                abDic.Add(strs[i], temp);
            }
        }

        // 加载 AB 包
        if (!abDic.ContainsKey(abName)) {
    
    
            AssetBundle ab = AssetBundle.LoadFromFile(AB_DIRECTORY + abName);
            abDic.Add(abName, ab);
        }
    }

    /// <summary>
    /// 使用泛型加载 AB 包内的资源
    /// </summary>
    /// <param name="abName"></param>
    /// <param name="resName"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T LoadRes<T>(string abName, string resName) where T : Object {
    
    
        // 加载 AB 包
        LoadAB(abName);

        return abDic[abName].LoadAsset(resName) as T;
    }

    /// <summary>
    /// 加载 AB 包内的资源
    /// </summary>
    /// <param name="abName"></param>
    /// <param name="resName"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    public Object LoadRes(string abName, string resName, Type type) {
    
    
        // 加载 AB 包
        LoadAB(abName);

        return abDic[abName].LoadAsset(resName, type);
    }

    /// <summary>
    /// 异步加载 AB 包资源(加载 AB 包同步,加载资源异步)
    /// </summary>
    /// <param name="abName"></param>
    /// <param name="resName"></param>
    /// <param name="type"></param>
    /// <param name="callBack"></param>
    public void LoadResAsync(string abName, string resName, Type type, UnityAction<Object> callBack) {
    
    
        // 启动协程
        StartCoroutine(ReallyLoadResAsync(abName, resName, type, callBack));
    }

    /// <summary>
    /// 异步加载协程(加载 AB 包同步,加载资源异步)
    /// </summary>
    /// <param name="abName"></param>
    /// <param name="resName"></param>
    /// <param name="type"></param>
    /// <param name="callBack"></param>
    /// <returns></returns>
    private IEnumerator ReallyLoadResAsync(string abName, string resName, Type type, UnityAction<Object> callBack) {
    
    
        // 加载 AB 包
        LoadAB(abName);

        // 异步加载资源
        AssetBundleRequest abr = abDic[abName].LoadAssetAsync(resName, type);
        yield return abr;

        // 执行回调委托
        callBack(abr.asset);
    }

    /// <summary>
    /// 异步加载 AB 包资源(加载 AB 包同步,加载资源异步)
    /// </summary>
    /// <param name="abName"></param>
    /// <param name="resName"></param>
    /// <param name="callBack"></param>
    public void LoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object {
    
    
        // 启动协程
        StartCoroutine(ReallyLoadResAsync(abName, resName, callBack));
    }

    /// <summary>
    /// 异步加载协程(加载 AB 包同步,加载资源异步)
    /// </summary>
    /// <param name="abName"></param>
    /// <param name="resName"></param>
    /// <param name="type"></param>
    /// <param name="callBack"></param>
    /// <returns></returns>
    private IEnumerator ReallyLoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object {
    
    
        // 加载 AB 包
        LoadAB(abName);

        // 异步加载资源
        AssetBundleRequest abr = abDic[abName].LoadAssetAsync<T>(resName);
        yield return abr;

        // 执行回调委托
        callBack(abr.asset as T);
    }


    /// <summary>
    /// 卸载指定 AB 包
    /// </summary>
    /// <param name="abName"></param>
    /// <param name="unloadAllLoadedObjects"></param>
    public void UnLoad(string abName, bool unloadAllLoadedObjects = false) {
    
    
        if (abDic.ContainsKey(abName)) {
    
    
            abDic[abName].Unload(unloadAllLoadedObjects);
            abDic.Remove(abName);
        }
    }

    /// <summary>
    /// 卸载所有 AB 包
    /// </summary>
    /// <param name="unloadAllLoadedObjects"></param>
    public void UnLoadAll(bool unloadAllLoadedObjects = false) {
    
    
        AssetBundle.UnloadAllAssetBundles(unloadAllLoadedObjects);
        abDic.Clear();
        mainAB   = null;
        manifest = null;
    }
}

猜你喜欢

转载自blog.csdn.net/zheliku/article/details/131115211