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

  • 8
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值