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

该代码实现了一个用于管理Unity3DAssetBundle的类AssetBundleMgr,它负责同步和异步加载AB包,处理依赖关系,并提供资源的加载和卸载功能。AssetBundleMgr使用静态单例模式,确保游戏运行期间只有一个实例存在。
摘要由CSDN通过智能技术生成
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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔗理苦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值