unity 团结开发小游戏,加载AssetBundles

1.场景中单独放一个物体,添加脚本ABsLoad

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;


public class ABsLoad : MonoBehaviour
{
    public static ABsLoad instance;

    /// <summary>
    ///主 AssetBundle
    /// </summary>
    public static AssetBundle mainAssetBundle = null;
    /// <summary>
    /// 主AssetBundle清单
    /// </summary>
    public static AssetBundleManifest assetBundleManifest = null;
    /// <summary>
    /// AssetBundle地址
    /// </summary>
    public static string urlAssetBundle = "https://api.paratime.cc/streamingassets";
    /// <summary>
    /// 主包名字
    /// </summary>
    public static string mainAssetBundleName = "WebGL";
    /// <summary>
    /// 分包字典
    /// </summary>
    public Dictionary<string, AssetBundle> assetBundleDictionary = new Dictionary<string, AssetBundle>(); // AssetBundle 字典


    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(this);
        }
    }



    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(LoadMainWithDependencies(urlAssetBundle, mainAssetBundleName));
    }



    /// <summary>
    /// 外部调用加载资源
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="bundleNames"></param>
    /// <param name="resourceName"></param>
    /// <param name="callback"></param>
    public void LoadResourcek<T>(string bundleNames, string resourceName, Action<T> callback) where T : UnityEngine.Object
    {
        StartCoroutine(LoadFromNetwork<T>(bundleNames, resourceName, callback));
    }

    /// <summary>
    /// 从网络加载
    /// </summary>
    /// <param name="url"></param>
    /// <returns></returns>
    IEnumerator LoadFromNetwork<T>(string bundleNames, string resourceName, Action<T> callback) where T : UnityEngine.Object
    {
        // 加载pictrue分包
        string pictrueUrl = urlAssetBundle + "/" + bundleNames;
        Debug.Log("分包地址:" + pictrueUrl);
        AssetBundleRequest assetBundleRequest = null;

        //判断字典中是否有资源
        if (!assetBundleDictionary.ContainsKey(bundleNames))
        {
            //没有这个资源下载
            using (UnityWebRequest pictrueRequest = UnityWebRequestAssetBundle.GetAssetBundle(pictrueUrl))
            {
                Debug.Log("加载分包:" + bundleNames);
                yield return pictrueRequest.SendWebRequest();
                if (pictrueRequest.result == UnityWebRequest.Result.Success)
                {
                    AssetBundle aBundle = DownloadHandlerAssetBundle.GetContent(pictrueRequest);
                    if (aBundle != null)
                    {
                        assetBundleDictionary.Add(bundleNames, aBundle);
                        Debug.Log("添加分包到字典:" + bundleNames);
                        assetBundleRequest = aBundle.LoadAssetAsync<T>(resourceName);

                    }
                    //aBundle.Unload(false);
                }
                else
                {
                    Debug.Log("加载pictrue分包失败:" + pictrueRequest.result);
                }
            }
        }
        else
        {
            Debug.Log("有资源:" + pictrueUrl);
            assetBundleRequest = assetBundleDictionary[bundleNames].LoadAssetAsync<T>(resourceName);
        }


        //异步加载AB包中的资源的类中的asset属性代表实际加载出的资源 要转换成实际的类型
        T loadedAsset = (T)assetBundleRequest.asset;
        callback?.Invoke(loadedAsset); // 通过回调返回结果
    }


    /// <summary>
    /// 加载主依赖项
    /// </summary>
    /// <param name="urlManifest">网络地址</param>
    /// <param name="mainName">名字</param>
    /// <returns></returns>
    IEnumerator LoadMainWithDependencies(string urlManifest, string mainName)
    {
        string mainUrl = urlManifest + "/" + mainName;
        // 加载依赖清单
        using (UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle(mainUrl))
        {
            yield return www.SendWebRequest();

            if (www.result == UnityWebRequest.Result.Success)
            {
                AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www);
                assetBundleManifest = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
                Debug.Log("获取主清单:" + mainUrl);
                bundle.Unload(false);
            }

            if (assetBundleManifest == null) yield break;
            // 获取主包的依赖项
            string[] dependencies = assetBundleManifest.GetAllDependencies(mainName);
            Debug.Log("主包依赖项数量:" + dependencies.Length);
            // 先加载所有依赖包
            foreach (string dependency in dependencies)
            {
                Debug.Log("主包依赖包位置:" + urlManifest + "/" + dependency);
                string url = urlManifest + "/" + dependency;
                using (UnityWebRequest depRequest = UnityWebRequestAssetBundle.GetAssetBundle(url))
                {
                    yield return depRequest.SendWebRequest();
                    if (depRequest.result == UnityWebRequest.Result.Success)
                    {
                        AssetBundle depBundle = DownloadHandlerAssetBundle.GetContent(depRequest);
                        if (depBundle != null && !assetBundleDictionary.ContainsKey(dependency))
                        {
                            assetBundleDictionary.Add(dependency, depBundle);
                            Debug.Log("添加依赖包到字典:" + dependency);
                        }

                    }
                }
            }

            // 加载主包
            using (UnityWebRequest mainRequest = UnityWebRequestAssetBundle.GetAssetBundle(mainUrl))
            {
                yield return mainRequest.SendWebRequest();
                if (mainRequest.result == UnityWebRequest.Result.Success)
                {
                    mainAssetBundle = DownloadHandlerAssetBundle.GetContent(mainRequest);
                    Debug.Log("主包加载完成!");
                    // 使用主包资源...
                    //mainAssetBundle.Unload(false);
                }
            }
        }
    }


    /// <summary>
    /// AssetBundle属性资源管理
    /// </summary>
    /// <param name="bundle">AssetBundle</param>
    /// <param name="isTrue">false常用方式,保留已加载的资源;true会销毁所有从该 bundle 加载的资源</param>
    public void ProperResourceManagement(AssetBundle bundle, bool isTrue)
    {

        bundle.Unload(isTrue);

        // 对于实例化的对象,需要手动销毁
        //Destroy(obj);
        // 对于材质等资源,如果不再需要,可以手动销毁
        // Destroy(mat); // 注意:如果其他对象还在使用该材质,这会导致问题
    }


}

2.两种方式调用

cs 复制代码
using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    public RawImage raw;

    public void OnBtnClick()
    {
        ABsLoad.instance.LoadResourcek<Texture2D>("pictrue", "2.jpg", onCallBack);
    }
    private void onCallBack(Texture2D d)
    {
        raw.texture = d;
    }
    public void OnBtnClick2()
    {
        ABsLoad.instance.LoadResourcek<Texture2D>("pictrue", "1.jpg", (res) => {
            raw.texture = res;
        });

    }

}
相关推荐
℡枫叶℡1 天前
Unity - Import Activity Window 资源导入诊断信息窗口
unity·资源导入诊断
TO_ZRG1 天前
Unity 证书校验
unity·游戏引擎
mxwin1 天前
Unity Shader 切线空间数据是如何计算出来的
unity·游戏引擎·shader
mxwin2 天前
Unity Shader 法线贴图跟切线空间有什么关系
unity·游戏引擎·贴图·shader
mxwin2 天前
Unity Shader 贴图和采样的关系 如何保证贴图清晰
unity·游戏引擎·贴图·shader
心前阳光2 天前
Unity之使用火山引擎实现文字提问流式回复
unity·游戏引擎·火山引擎
mxwin2 天前
Unity Shader 什么是球谐光照 原理是什么
unity·游戏引擎·shader
心前阳光2 天前
Unity之使用火山引擎实现语音识别
unity·语音识别·火山引擎
心前阳光2 天前
Unity之使用火山引擎实现流式语音合成
unity·游戏引擎·火山引擎