官方文档 https://unity3d.com/cn/learn/tutorials/topics/best-practices/assetbundle-usage-patterns
示例代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestGUI : MonoBehaviour {
public AssetBundle ab;
public Object[] assets;
void Start () {
StartCoroutine(LoadModel());
}
IEnumerator LoadModel()
{
yield return null;
string url = string.Format("file://{0}/model_lady01.model", Application.streamingAssetsPath);
WWW www = new WWW(url);
while (!www.isDone)
yield return www;
if (!string.IsNullOrEmpty(www.error)) {
Debug.LogError("加载资源失败 " + url + "\n" + www.error);
}else{
ab = www.assetBundle;
assets = ab.LoadAllAssets();
OnLoadCompleted(assets);
}
}
void OnLoadCompleted(Object[] assets)
{
GameObject mainAsset = null;
//找到模型资源作为主资源
for(int i=0; i < assets.Length; i++) {
if (assets[i].name.StartsWith("model_")) {
mainAsset = assets[i] as GameObject;
break;
}
}
if (mainAsset == null) {
Debug.LogErrorFormat("not model asset. url={0}", "");
return;
}
GameObject model = GameObject.Instantiate(mainAsset);
}
private void OnGUI() {
if (GUI.Button(new Rect(0, 0, 200, 40), "Unload(false)")) {
ab.Unload(false);//释放镜像资源
}
if (GUI.Button(new Rect(0, 50, 200, 40), "Unload(true)")) {
ab.Unload(true);//释放资源
}
}
}
运行测试
调用AssetBundle.Unload(false)
销毁AssetBundle资源,保留从AssetBundle加载出来的资源。
调用AssetBundle.Unload(true)
销毁AssetBundle资源,以及从AssetBundle加载出来的资源。
如果使用了AssetBundle.Unload(false), 那么从AssetBundle加载出来的资源仅能以下面两种方式御载
1、消除对资源的所有引用,然后手动调用Resources.UnloadUnusedAssets()
2、以非叠加方式切换场景
官方说明
解决方案: 改成异步加载资源
private IEnumerator LoadTextureFromWWW(string url)
{
yield return null;
WWW www = new WWW(url);
while (!www.isDone)
yield return www;
if (!string.IsNullOrEmpty(www.error))
{
Debug.LogErrorFormat("加载贴图出错\n{0} url={1}", www.error, www.url);
}
else
{
AssetBundle ab = www.assetBundle;
if (ab != null)
{
string tex_name = Path.GetFileNameWithoutExtension(url);
AssetBundleRequest request = ab.LoadAssetAsync(tex_name);
yield return request;
OnLoadTextureCompleted(request.asset as Texture2D);
//上面须用LoadAssetAsync,否则Unload可能导致报错
ab.Unload(false);//释放镜像资源,否则重复加载同名同后缀的ab资源会报错
}
}
}
//清理内存
Resources.UnloadUnusedAssets();
System.GC.Collect();