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;
        });

    }

}
相关推荐
cyr___3 小时前
Unity教程(二十七)技能系统 黑洞技能(下)黑洞状态
学习·游戏·unity·游戏引擎
张老师带你学4 小时前
Unity 科幻武器系列
科技·游戏·unity·模型·游戏美术
平行云6 小时前
虚拟直播混合式2D/3D应用程序实时云渲染推流解决方案
linux·unity·云原生·ue5·图形渲染·实时云渲染·像素流送
cyr___6 小时前
Unity教程(二十六)技能系统 黑洞技能(上)基础实现
学习·游戏·unity·游戏引擎
张老师带你学7 小时前
Unity 机器人 humanoid +shader效果
科技·游戏·unity·游戏引擎·模型
星河耀银海13 小时前
Unity基础:UI组件详解:Toggle开关的状态控制
ui·unity·lucene
mxwin14 小时前
Unity URP 法线贴图:世界空间 vs 切线空间 深度解析两种法线贴图格式在实时渲染中的核心差异、适用场景与性能权衡
unity·游戏引擎·贴图
℡枫叶℡2 天前
Unity - 全局配置Unity工程的资源检索的目录
unity·资源检索配置
mxwin2 天前
Unity URP 下 TBN 矩阵学习 切线空间、tangent.w 与镜像 UV 的那些坑
学习·unity·矩阵·shader