理解AssetBundle.Unload()

作者:追风剑情 发布于:2018-12-12 15:50 分类:Unity3d

官方文档 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()
1111.png

调用AssetBundle.Unload(false)
销毁AssetBundle资源,保留从AssetBundle加载出来的资源。
2222.png

调用AssetBundle.Unload(true)
销毁AssetBundle资源,以及从AssetBundle加载出来的资源。
3333.png

4444.png

如果使用了AssetBundle.Unload(false), 那么从AssetBundle加载出来的资源仅能以下面两种方式御载
1、消除对资源的所有引用,然后手动调用Resources.UnloadUnusedAssets()
2、以非叠加方式切换场景
官方说明

7777.png

如果用WWW加载时报以下错
33333.png
11111.png
222.png

解决方案: 改成异步加载资源

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

标签: Unity3d

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号