unity 团结开发小游戏,加载AssetBundles(第二种方法)

1.加载代码

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


public class ABsLoad : MonoBehaviour
{
    public static ABsLoad instance;

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


    /// <summary>
    /// 外部调用加载资源包
    /// </summary>
    /// <param name="bundleUrl">资源包位置</param>
    /// <param name="bundleNames">资源包名字</param>
    /// <param name="callback">返回</param>
    public void LoadBundle(string bundleUrl, string bundleNames, Action callback)
    {
        StartCoroutine(LoadBundleUrl(bundleUrl, bundleNames, callback));
    }
    /// <summary>
    /// 从网络加载资源包
    /// </summary>
    /// <param name="bundleUrl">资源包位置</param>
    /// <param name="bundleNames">资源包名字</param>
    /// <param name="callback">返回</param>
    /// <returns></returns>
    IEnumerator LoadBundleUrl(string bundleUrl, string bundleNames, Action callback)
    {
        // 加载pictrue分包
        string pictrueUrl = bundleUrl + "/" + bundleNames;
        Debug.Log("包地址:" + pictrueUrl);
        //判断字典中是否有资源
        if (!GameData.assetBundleDictionary.ContainsKey(bundleNames))
        {
            //没有这个资源下载
            using (UnityWebRequest pictrueRequest = UnityWebRequestAssetBundle.GetAssetBundle(pictrueUrl))
            {
                yield return pictrueRequest.SendWebRequest();
                if (pictrueRequest.result == UnityWebRequest.Result.Success)
                {
                    AssetBundle aBundle = DownloadHandlerAssetBundle.GetContent(pictrueRequest);
                    if (aBundle != null)
                    {
                        GameData.assetBundleDictionary.Add(bundleNames, aBundle);
                        Debug.Log("添加分包到字典:" + bundleNames);
                        callback?.Invoke(); // 通过回调返回结果
                    }
                }
                else
                {
                    Debug.Log("加载pictrue分包失败:" + pictrueRequest.result);
                }
            }
        }
        else
        {
            Debug.Log("已存在!");
            callback?.Invoke(); // 通过回调返回结果
        }
    }

    /// <summary>
    /// 从资源包里面加载资源
    /// </summary>
    /// <typeparam name="T">资源类型</typeparam>
    /// <param name="bundleNames">资源包名字</param>
    /// <param name="resourceNames">资源名字</param>
    /// <param name="callback">返回资源</param>
    public void LoadBundleResource<T>(string bundleNames, string resourceNames, Action<T> callback) where T : UnityEngine.Object
    {
        AssetBundleRequest assetBundleRequest = null;
        if (GameData.assetBundleDictionary.ContainsKey(bundleNames))
        {
            //Debug.Log("有资源:" + bundleNames);
            assetBundleRequest = GameData.assetBundleDictionary[bundleNames].LoadAssetAsync<T>(resourceNames);
            //异步加载AB包中的资源的类中的asset属性代表实际加载出的资源 要转换成实际的类型
            T loadedAsset = (T)assetBundleRequest.asset;
            callback?.Invoke(loadedAsset); // 通过回调返回结果
        }
        else
        {
            Debug.Log("没找到包!" + bundleNames);
        }

    }
    /// <summary>
    /// 卸载资源包
    /// </summary>
    /// <param name="bundleNames">AssetBundle在字典里面的Key</param>
    /// <param name="isTrue">false常用方式,保留已加载的资源;true会销毁所有从该 bundle 加载的资源</param>
    public void UnLoadBundleResource(string bundleNames, bool isTrue)
    {
        //判断字典中是否有AssetBundle资源
        if (GameData.assetBundleDictionary.ContainsKey(bundleNames))
        {
            AssetBundle bundle = GameData.assetBundleDictionary[bundleNames];
            GameData.assetBundleDictionary.Remove(bundleNames);
            bundle.Unload(isTrue);
        }
    }

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

    /// <summary>
    ///  从网络加载bundle
    /// </summary>
    /// <typeparam name="T">返回资源格式</typeparam>
    /// <param name="bundleNames">资源所在bundle名称</param>
    /// <param name="resourceName">资源名字</param>
    /// <param name="isAdd">是否添加到字典</param>
    /// <param name="callback">返回</param>
    /// <returns></returns>
    IEnumerator LoadFromNetwork<T>(string bundleNames, string resourceName, bool isAdd, Action<T> callback) where T : UnityEngine.Object
    {
        // 加载pictrue分包
        string pictrueUrl = GameData.urlAssetBundle + "/" + bundleNames;
        Debug.Log("分包地址:" + pictrueUrl);
        AssetBundleRequest assetBundleRequest = null;

        //判断字典中是否有资源
        if (!GameData.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)
                    {
                        Debug.LogError("加载AssetBundle失败,aBundle为null");
                        callback?.Invoke(null);
                        yield break;
                    }
                    assetBundleRequest = aBundle.LoadAssetAsync<T>(resourceName);
                    if (isAdd)
                    {

                        GameData.assetBundleDictionary.Add(bundleNames, aBundle);
                        Debug.Log("添加分包到字典:" + bundleNames);
                        //异步加载AB包中的资源的类中的asset属性代表实际加载出的资源 要转换成实际的类型
                        T loadedAsset = (T)assetBundleRequest.asset;
                        callback?.Invoke(loadedAsset); // 通过回调返回结果
                    }
                    else
                    {
                        Debug.Log("资源单独加载:" + bundleNames);
                        //异步加载AB包中的资源的类中的asset属性代表实际加载出的资源 要转换成实际的类型
                        T loadedAsset = (T)assetBundleRequest.asset;
                        callback?.Invoke(loadedAsset); // 通过回调返回结果
                        aBundle.Unload(false);
                        Debug.Log("资源已卸载:" + bundleNames);
                    }

                }
                else
                {
                    Debug.Log("加载pictrue分包失败:" + pictrueRequest.result);
                }
            }
        }
        else
        {
            Debug.Log("有资源:" + pictrueUrl);
            assetBundleRequest = GameData.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>
    /// <param name="callback">返回</param>
    private void LoadMain(string urlManifest, string mainName, Action callback)
    {
        StartCoroutine(LoadMainWithDependencies(urlManifest, mainName, callback));
    }

    /// <summary>
    /// 加载主依赖项-自己拼接
    /// </summary>
    /// <param name="urlManifest">网络地址</param>
    /// <param name="mainName">名字</param>
    /// <returns></returns>
    IEnumerator LoadMainWithDependencies(string urlManifest, string mainName, Action callback)
    {

        string mainUrl = urlManifest + "/" + mainName;
        AssetBundleManifest assetBundleManifest = null;
        // 加载依赖清单
        using (UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle(mainUrl))
        {
            yield return www.SendWebRequest();

            if (www.result == UnityWebRequest.Result.Success)
            {
                AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www);
                if (bundle != null)
                {
                    assetBundleManifest = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
                    Debug.Log("获取主清单:" + mainUrl);
                    bundle.Unload(false);
                }
                else
                {
                    Debug.LogError("获取AssetBundle失败:" + mainUrl);
                    yield break;
                }
            }
            else
            {
                Debug.LogError("网络请求失败:" + www.error);
                yield break;
            }

            if (assetBundleManifest == null)
            {
                Debug.LogError("获取AssetBundleManifest失败");
                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 && !GameData.assetBundleDictionary.ContainsKey(dependency))
                        {
                            GameData.assetBundleDictionary.Add(dependency, depBundle);
                            Debug.Log("添加依赖包到字典:" + dependency);
                        }

                    }
                }
            }

            // 加载主包
            using (UnityWebRequest mainRequest = UnityWebRequestAssetBundle.GetAssetBundle(mainUrl))
            {
                yield return mainRequest.SendWebRequest();
                if (mainRequest.result == UnityWebRequest.Result.Success)
                {
                    AssetBundle mainAssetBundle = DownloadHandlerAssetBundle.GetContent(mainRequest);
                    Debug.Log("主包加载完成!");
                    callback?.Invoke(); // 通过回调返回结果
                    mainAssetBundle.Unload(false);
                }
            }
        }
    }



}

2.数据存储

cs 复制代码
public static class GameData
{
    /// <summary>
    /// 资源包所在服务器的文件夹
    /// </summary>
    public static string urlAssetBundle = "http://XX./WebGL";
    /// <summary>
    /// AssetBundle 分包字典
    /// </summary>
    public static Dictionary<string, AssetBundle> assetBundleDictionary = new Dictionary<string, AssetBundle>();
}

3.调用

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

public class StarBorder : MonoBehaviour
{
    [Header("资源包名字")]
    public string BundleName = "starone";
    [Header("好感度")]
    private string haogan = "1111";
    public Sprite heartRed;
    public Sprite heartGrey;
    public List<Image> hearts = new List<Image>();
    public GameObject heartBlue;
    [Header("上方数字展示栏")]
    public List<Text> numberShow = new List<Text>();
    // Start is called before the first frame update
    void Start()
    {

        ABsLoad.instance.LoadBundle(GameData.urlAssetBundle,BundleName, () =>
        {
            GetHeart();
            GetNumberShow();
        });

    }

    public void ClickHaoGan()
    {
        SmallGame.Instance.TanShow(haogan);
    }

    /// <summary>
    /// 好感度
    /// </summary>
    public void GetHeart()
    {
        ABsLoad.instance.LoadBundleResource<GameObject>(BundleName, "心仪进度.prefab", (res) =>
        {
            heartBlue = Instantiate(res, this.transform);
            heartBlue.name = "好感度";
            heartBlue.transform.GetChild(5).GetComponent<Button>().onClick.AddListener(() =>
            {
                TipShow.Instance.TanShow(haogan);
            });
            ABsLoad.instance.LoadBundleResource<Sprite>(BundleName, "心2.png", (res) =>
            {
                heartGrey = res;
                for (int i = 0; i < 5; i++)
                {
                    heartBlue.transform.GetChild(i).GetComponent<Image>().sprite = heartGrey;
                }
            });

            ABsLoad.instance.LoadBundleResource<Sprite>(BundleName, "心1.png", (res) =>
            {
                heartRed = res;

            });
        });
    }

    /// <summary>
    /// 设置上方栏
    /// </summary>
    public void GetNumberShow()
    {
        numberShow.Clear();
        ABsLoad.instance.LoadBundleResource<GameObject>(BundleName, "上1.prefab", (res) =>
        {
            GameObject GO = Instantiate(res, this.transform);
            GO.name = "上1";
            Text t = GO.transform.GetChild(0).GetComponent<Text>();
            SetFont(t);
            numberShow.Add(t);
        });
  
  


    }
    /// <summary>
    /// 设置字体
    /// </summary>
    /// <param name="t"></param>
    void SetFont(Text t)
    {
        t.font = SmallGame.Instance.usFont;
        t.text = "0";
    }




}
相关推荐
魔士于安1 小时前
Unity UI图片 复活节UI,卡通风格
游戏·ui·unity·游戏引擎·材质·贴图
魔士于安2 小时前
unity 卡通风整套资源 小鸟N套带动作+一套卡通风村落 和 相关道具+落叶粒子效果 buildin
游戏·unity·游戏引擎·贴图·模型
伽蓝_游戏3 小时前
第一章:解构游戏资源
游戏·unity·性能优化·c#·游戏引擎·游戏程序·assetbundle
星辰徐哥4 小时前
Unity C#入门:Visual Studio与Unity的关联配置
unity·c#·visual studio
Sparkle Star5 小时前
Unity VRTK4包导入和依赖关系
unity·游戏引擎
WiChP6 小时前
【V0.1B7】从零开始的2D游戏引擎开发之路
游戏引擎
Sparkle Star8 小时前
Unity VRTK4+SteamVR传送组件使用和层级关系
unity·游戏引擎
cheniie8 小时前
Windows下Unity开发VisionPro应用
windows·unity·vision pro
伽蓝_游戏9 小时前
UGUI源码剖析 (24):常用插件扩展介绍
ui·unity·c#·游戏引擎·游戏程序