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