1.相关内容导入

1.相关内容导入


1.1 知识点

ILRuntime导入,开启unsafe

AB包工具导入

基础框架、AB包和AB包上传下载相关代码导入

删除热更Demo中无用信息,报错代码注释了就行,可以方便之后假如写的话有模版对应


修改AssetBundleManager中加载路径相关代码,改成先判断持久文件夹有没有相关的包或清单

private string StreamingUrl
{
    get { return Application.streamingAssetsPath + "/"; }
}

private string PersistentUrl
{
    get { return Application.persistentDataPath + "/"; }
}

/// <summary>
/// 加载主 AssetBundle 和 AssetBundle 清单
/// </summary>
private void LoadMainAssetBundleAndAssetBundleManifest()
{
    if (mainAssetBundle == null)
    {
        string path = File.Exists(PersistentUrl + mainAssetBundleName)
            ? PersistentUrl + mainAssetBundleName
            : StreamingUrl + mainAssetBundleName;
        mainAssetBundle = AssetBundle.LoadFromFile(path);
        assetBundleManifest = mainAssetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    }
}

/// <summary>
/// 加载 AssetBundle 的依赖项
/// </summary>
private void LoadAssetBundleDependencies(string assetBundleName)
{
    LoadMainAssetBundleAndAssetBundleManifest();

    string[] strs = assetBundleManifest.GetAllDependencies(assetBundleName);
    for (int i = 0; i < strs.Length; i++)
    {
        if (!assetBundleDictionary.ContainsKey(strs[i]))
        {
            string path = File.Exists(PersistentUrl + strs[i])
                ? PersistentUrl + strs[i]
                : StreamingUrl + strs[i];
            AssetBundle ab = AssetBundle.LoadFromFile(path);
            assetBundleDictionary.Add(strs[i], ab);
        }
    }
}

/// <summary>
/// 加载目标 AssetBundle
/// </summary>
private void LoadAssetBundleTarget(string assetBundleName)
{
    if (!assetBundleDictionary.ContainsKey(assetBundleName))
    {
        string path = File.Exists(PersistentUrl + assetBundleName)
            ? PersistentUrl + assetBundleName
            : StreamingUrl + assetBundleName;
        AssetBundle assetBundle = AssetBundle.LoadFromFile(path);
        assetBundleDictionary.Add(assetBundleName, assetBundle);
    }
}

1.2 知识点代码

using System.Collections;
using System.Collections.Generic;
using System.IO;
using BaseFramework;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// AssetBundle管理器
/// </summary>
public class AssetBundleManager : BaseSingletonInMonoBehaviour<AssetBundleManager>
{
    #region 变量

    private AssetBundle mainAssetBundle = null; // 主 AssetBundle
    private AssetBundleManifest assetBundleManifest = null; // AssetBundle 清单

    private Dictionary<string, AssetBundle>
        assetBundleDictionary = new Dictionary<string, AssetBundle>(); // AssetBundle 字典


    private string StreamingUrl
    {
        get { return Application.streamingAssetsPath + "/"; }
    }
    
    private string PersistentUrl
    {
        get { return Application.persistentDataPath + "/"; }
    }

    /// <summary>
    /// 获取主 AssetBundle 的名称
    /// </summary>
    private string mainAssetBundleName
    {
        get
        {
#if UNITY_IOS
            return "IOS";
#elif UNITY_ANDROID
            return "Android";
#else
            return "PC";
#endif
        }
    }

    #endregion

    #region 加载包

    /// <summary>
    /// 加载主 AssetBundle 和 AssetBundle 清单
    /// </summary>
    private void LoadMainAssetBundleAndAssetBundleManifest()
    {
        if (mainAssetBundle == null)
        {
            string path = File.Exists(PersistentUrl + mainAssetBundleName)
                ? PersistentUrl + mainAssetBundleName
                : StreamingUrl + mainAssetBundleName;
            mainAssetBundle = AssetBundle.LoadFromFile(path);
            assetBundleManifest = mainAssetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        }
    }

    /// <summary>
    /// 加载 AssetBundle 的依赖项
    /// </summary>
    private void LoadAssetBundleDependencies(string assetBundleName)
    {
        LoadMainAssetBundleAndAssetBundleManifest();

        string[] strs = assetBundleManifest.GetAllDependencies(assetBundleName);
        for (int i = 0; i < strs.Length; i++)
        {
            if (!assetBundleDictionary.ContainsKey(strs[i]))
            {
                string path = File.Exists(PersistentUrl + strs[i])
                    ? PersistentUrl + strs[i]
                    : StreamingUrl + strs[i];
                AssetBundle ab = AssetBundle.LoadFromFile(path);
                assetBundleDictionary.Add(strs[i], ab);
            }
        }
    }

    /// <summary>
    /// 加载目标 AssetBundle
    /// </summary>
    private void LoadAssetBundleTarget(string assetBundleName)
    {
        if (!assetBundleDictionary.ContainsKey(assetBundleName))
        {
            string path = File.Exists(PersistentUrl + assetBundleName)
                ? PersistentUrl + assetBundleName
                : StreamingUrl + assetBundleName;
            AssetBundle assetBundle = AssetBundle.LoadFromFile(path);
            assetBundleDictionary.Add(assetBundleName, assetBundle);
        }
    }

    /// <summary>
    /// 加载目标 AssetBundle 和其依赖项
    /// </summary>
    private void LoadAssetBundleTargetAndDependencies(string assetBundleName)
    {
        LoadAssetBundleDependencies(assetBundleName);
        LoadAssetBundleTarget(assetBundleName);
    }

    #endregion

    #region 同步加载

    /// <summary>
    /// 如果资源是 GameObject,则实例化;否则返回原始资源
    /// </summary>
    private T InstantiateIfGameObject<T>(T resource) where T : Object
    {
        if (resource is GameObject)
        {
            return Instantiate(resource);
        }
        else
        {
            return resource;
        }
    }

    /// <summary>
    /// 同步加载 AssetBundle 中的资源
    /// </summary>
    public T LoadAssetBundleResource<T>(string assetBundleName, string resourceName) where T : Object
    {
        LoadAssetBundleTargetAndDependencies(assetBundleName);

        T resource = assetBundleDictionary[assetBundleName].LoadAsset<T>(resourceName);

        return InstantiateIfGameObject<T>(resource);
    }

    /// <summary>
    /// 同步加载 AssetBundle 中的资源,指定资源类型
    /// </summary>
    public Object LoadAssetBundleResource(string assetBundleName, string resourceName, System.Type type)
    {
        LoadAssetBundleTargetAndDependencies(assetBundleName);

        Object resource = assetBundleDictionary[assetBundleName].LoadAsset(resourceName, type);

        return InstantiateIfGameObject(resource);
    }

    /// <summary>
    /// 同步加载 AssetBundle 中的资源
    /// </summary>
    public Object LoadAssetBundleResource(string assetBundleName, string resourceName)
    {
        LoadAssetBundleTargetAndDependencies(assetBundleName);

        Object resource = assetBundleDictionary[assetBundleName].LoadAsset(resourceName);

        return InstantiateIfGameObject(resource);
    }

    #endregion

    #region 异步加载

    /// <summary>
    /// 如果资源是 GameObject,则实例化后执行回调;否则直接执行回调
    /// </summary>
    private void InstantiateIfGameObjectAndCallBack<T>(T resource, UnityAction<T> callBack) where T : Object
    {
        if (resource is GameObject)
            callBack(Instantiate(resource) as T);
        else
            callBack(resource as T);
    }

    /// <summary>
    /// 异步加载 AssetBundle 中的资源
    /// </summary>
    public void LoadAssetBundleResourceAsync<T>(string assetBundleName, string resourceName, UnityAction<T> callBack)
        where T : Object
    {
        StartCoroutine(LoadAssetBundleResourceAsyncCoroutine<T>(assetBundleName, resourceName, callBack));
    }

    /// <summary>
    /// 异步加载 AssetBundle 中的资源,指定资源类型
    /// </summary>
    private IEnumerator LoadAssetBundleResourceAsyncCoroutine<T>(string assetBundleName, string resourceName,
        UnityAction<T> callBack) where T : Object
    {
        LoadAssetBundleTargetAndDependencies(assetBundleName);

        AssetBundleRequest assetBundleRequest = assetBundleDictionary[assetBundleName].LoadAssetAsync<T>(resourceName);
        yield return assetBundleRequest;

        InstantiateIfGameObjectAndCallBack<T>(assetBundleRequest.asset as T, callBack);
    }

    /// <summary>
    /// 异步加载 AssetBundle 中的资源,指定资源类型
    /// </summary>
    public void LoadAssetBundleResourceAsync(string assetBundleName, string resourceName, System.Type type,
        UnityAction<Object> callBack)
    {
        StartCoroutine(LoadAssetBundleResourceAsyncCoroutine(assetBundleName, resourceName, type, callBack));
    }

    /// <summary>
    /// 异步加载 AssetBundle 中的资源
    /// </summary>
    private IEnumerator LoadAssetBundleResourceAsyncCoroutine(string assetBundleName, string resourceName,
        System.Type type, UnityAction<Object> callBack)
    {
        LoadAssetBundleTargetAndDependencies(assetBundleName);

        AssetBundleRequest assetBundleRequest =
            assetBundleDictionary[assetBundleName].LoadAssetAsync(resourceName, type);
        yield return assetBundleRequest;

        InstantiateIfGameObjectAndCallBack(assetBundleRequest.asset, callBack);
    }

    /// <summary>
    /// 异步加载 AssetBundle 中的资源
    /// </summary>
    public void LoadAssetBundleResourceAsync(string assetBundleName, string resourceName, UnityAction<Object> callBack)
    {
        StartCoroutine(LoadAssetBundleResourceAsyncCoroutine(assetBundleName, resourceName, callBack));
    }

    /// <summary>
    /// 异步加载 AssetBundle 中的资源
    /// </summary>
    private IEnumerator LoadAssetBundleResourceAsyncCoroutine(string assetBundleName, string resourceName,
        UnityAction<Object> callBack)
    {
        LoadAssetBundleTargetAndDependencies(assetBundleName);

        AssetBundleRequest assetBundleRequest = assetBundleDictionary[assetBundleName].LoadAssetAsync(resourceName);
        yield return assetBundleRequest;

        InstantiateIfGameObjectAndCallBack(assetBundleRequest.asset, callBack);
    }

    #endregion

    #region 卸载包

    /// <summary>
    /// 卸载指定名称的 AssetBundle
    /// </summary>
    public void UnLoadAssetBundle(string name)
    {
        if (assetBundleDictionary.ContainsKey(name))
        {
            assetBundleDictionary[name].Unload(false);
            assetBundleDictionary.Remove(name);
        }
    }

    /// <summary>
    /// 清理所有 AssetBundle
    /// </summary>
    public void ClearAssetBundle()
    {
        AssetBundle.UnloadAllAssetBundles(false);
        assetBundleDictionary.Clear();
        mainAssetBundle = null;
        assetBundleManifest = null;
    }

    #endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏