unity资源释放(AssetBundle和Asset)

本节主要叙述下,资源的释放问题。
1、我们准备了下两个资源,并且要做打包处理。
这里写图片描述

代码的代码,很简陋,只是为了说明问题。代码如下:

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.IO; public class AssetBundleCreator { [MenuItem("AssetBundle/Build")] private static void BuildBundle() { string outDir = "Bundles"; if (!Directory.Exists(outDir)) { Directory.CreateDirectory(outDir); } AssetBundleBuild[] buildList = new AssetBundleBuild[1]; buildList[0].assetBundleName = "bundleDemo"; string[] bundleAssets = new string[2]; bundleAssets[0] = @"Assets\Prefabs\Cube.prefab"; bundleAssets[1] = @"Assets\Prefabs\bg.png"; buildList[0].assetNames = bundleAssets; BuildPipeline.BuildAssetBundles(outDir, buildList, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeB````````````` ildTarget); } } 

打包的结果:
这里写图片描述

2、测试过程
2.1 测试界面如下:
这里写图片描述

2.2 执行函数LoadBundle

private void LoadBundle(GameObject go) { StartCoroutine(LoadAssetBundle()); } private IEnumerator LoadAssetBundle() { string assetBundlePath = Application.dataPath + @"\..\Bundles\bundleDemo"; WWW www = new WWW(assetBundlePath); while (!www.isDone) { yield return null; } m_bundle = www.assetBundle; Debug.LogError("LoadAssetBundle over!"); } 

此时内存里面只有一个镜像文件,我们可以通过profile观测到:
这里写图片描述

2.3 执行一次UnloadBundleFalse,观察这个镜像文件是否被卸载掉了。

private void UnloadBundleFalse(GameObject go) { m_bundle.Unload(false); Debug.LogError("UnloadBundleFalse over!"); } 

此时AssetBundle镜像不存在了。
这里写图片描述

2.4 执行一次LoadBundle和LoadAsset,观察内存变换。
重新运行游戏,执行一次LoadBundle,上面已经叙述。然后执行一次LoadAsset。

private void LoadAsset(GameObject go) { m_textureAsset = (Texture)m_bundle.LoadAsset("bg", typeof(Texture)); m_texture.mainTexture = m_textureAsset; Debug.LogError("LoadAsset over!"); } 

此时,我们load一张图片赋值给了UITexture组件。观察Profile的内存状态:
这里写图片描述
再看镜像文件也在:
这里写图片描述

2.5 执行一次LoadBundle、LoadAsset和UnloadAsset,观察镜像文件是否在Asset是否在?

 private void UnloadAsset(GameObject go) { if (m_textureAsset != null) { Resources.UnloadAsset(m_textureAsset); } Debug.LogError("UnloadAsset over!"); } 

镜像文件在:
这里写图片描述
Asset不在了:
这里写图片描述

2.6 执行一次LoadBundle、LoadAsset和UnloadBundleTrue

 private void UnloadBundleTrue(GameObject go) { m_bundle.Unload(true); Debug.LogError("UnloadBundleTrue over!"); } 

镜像文件不在了:
这里写图片描述
Asset也不在了:
这里写图片描述

2.7 删除物体(绑定这个脚本的物体),然后执行一次 Resources.UnloadUnusedAssets();
测试代码:

 private void DestroyComponent(GameObject go) { StartCoroutine(DestroyComp()); } private IEnumerator DestroyComp() { Destroy(m_destroyComp.gameObject); yield return null; Resources.UnloadUnusedAssets(); } 

镜像文件在:
这里写图片描述
Asset不在:
这里写图片描述

叙述完毕。

总结:
1、镜像文件(bundle)用Unload(true),Unload(false)都可卸载掉。
2、Asset的卸载有两种方法,一种是指定类型资源强制卸载,函数为:
Resources.UnloadAsset(m_textureAsset); //这里的指定类型的资源不能是GameObject、Component,指定是Material、Texture、Mesh、AudioClip资源。
第二种卸载方式:Resources.UnloadUnusedAssets(); 这个要求必须是Asset在毫无其他引用的情况下,才能被卸载。所谓的毫无其他引用,比如你的texture被一个UI元素使用,或者被一个脚本的变量使用,没有赋值为null,这些都算作是有引用,那么即使你使用这个函数,也不能卸载Asset资源。另外补充说明一点就是:
Resources.UnloadUnusedAssets();和Resources.UnloadAsset(m_textureAsset);
前者效率很低,因为是遍历场景中的所有无引用的资源然后卸载;后者是指定卸载某一个资源,所以效率高。前者在场景切换的时候会被Unity自动调用一次,后者不会。
3、关于镜像文件和Asset以及GameObject的关系,我想画一个图来解释:
这里写图片描述

over!关于资源管理的代码,尚未完成,待叙。
最后给出,项目的完整代码:https://pan.baidu.com/s/1rvgPoTgMPNkpMOjrqSnP6g

原文链接:https://blog.csdn.net/wodownload2/article/details/80226435?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165277103516781435456458%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165277103516781435456458&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~times_rank-26-80226435-null-null.nonecase&utm_term=%E8%B5%84%E6%BA%90

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
文明发言,共建和谐米科社区
提交
头像

昵称

取消
昵称表情图片