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