Unity动态加载与内存关系3:AssetBundle (Addressable Assets)篇

15 篇文章 0 订阅

接着前两篇,我们继续测试 AssetBundle 方式的资源加载(实际是 用最新的Addressable Assets方式),然后再销毁与卸载,观察对应的内存变化。

这里不讲解 AssetBundle 的基本原理了,不了解的同学可以看官方文档:

https://docs.unity3d.com/Manual/AssetBundlesIntro.html

Addressable Assets 说明文档:

https://docs.unity3d.com/Packages/com.unity.addressables@1.8/manual/AddressableAssetsGettingStarted.html

 

先说结论:

1,不触发时,不占用什么资源

2,Addressables.LoadAssetAsync()会载入Mesh(几乎等同于 Resources.Load() )。

3,Instantiate()生成游戏体的时候,会载入对应的Texture,占用内存。

4,Addressables.ReleaseInstance() 销毁游戏体时,会马上释放小部分显存。Unity等待GC时机*(见下面注释1),再进行内存清理。

5,Resources.UnloadUnusedAssets() 可以清理内存,会把没有使用(或者资源=null)的资源清理掉。注意,官方建议在允许卡顿的情况下调用(比如loading界面),因为这是一个非常缓慢的操作。
 

注释1: 对于bundle(里面含有资源A/B/C),你可以部分加载(比如A),或者全部加载(ABC),但不能部分卸载。在bundle本身完全卸载之前,不会卸载任何东西.。除非你调用了Resources.UnloadUnusedAssets()。官方文档的解释:https://docs.unity3d.com/Packages/com.unity.addressables@1.8/manual/MemoryManagement.html

 

下面是试验过程,可以不看:

在空场景的摄像机上,挂上如下脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;

/// <summary>
/// 设计编写:常成功
/// 创建时间:2020/05/09 
/// 脚本功能:Addressables 测试, Instantiate()实例化后, 再卸载资源
/// 挂载位置:默认场景的摄像机上
/// </summary>


public class Test_A_Mem_2 : MonoBehaviour
{
    // 记录实例化的游戏体
    public List<GameObject> obj_list;


    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        // 按下[1], 加载资源并实例化
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            Debug.Log("Num 1: InstantiateAsync");
            Addressables.InstantiateAsync("Assets/Scenes/Test_Memery/prefabs/atc_geye@idle.prefab").Completed += OnLoadDone;
        }
        // 按下[2], 加载资源并实例化
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            Debug.Log("Num 2: InstantiateAsync");
            Addressables.InstantiateAsync("Assets/Scenes/Test_Memery/prefabs/atc_niya@idle.prefab").Completed += OnLoadDone;
        }
        // 按下[3], 加载资源并实例化
        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            Debug.Log("Num 3: InstantiateAsync");
            Addressables.InstantiateAsync("Assets/Scenes/Test_Memery/prefabs/Car_2C 1.prefab").Completed += OnLoadDone;
        }

        // 按下[右键], 以游戏体为单位, 逐个释放资源 
        if (Input.GetMouseButtonDown(1))
        {
            int tail_index = obj_list.Count - 1;
            // 相当于Destroy()
            Addressables.ReleaseInstance(obj_list[tail_index]);
            obj_list.RemoveAt(tail_index);
            Debug.Log("Mouse R:" + tail_index.ToString());
        }
        // 按下[D], 释放已经没有引用的资源
        if (Input.GetKeyDown(KeyCode.D))
        {
            obj_list = null;
            Debug.Log("Key D:");
            Resources.UnloadUnusedAssets();
        }

    }

    // 异步加载的回调函数
    private void OnLoadDone(UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle<GameObject> obj)
    {
        // In a production environment, you should add exception handling to catch scenarios such as a null result.
        if (obj.Result != null)
        {
            obj_list.Add(obj.Result);
        }
        else
        {
            Debug.LogWarning("LoadAssetAsync Error! ");
        }
    }
}

 

1

2

3

右1

右2

右3

D

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity中,可以使用AssetBundle来打包和加载资源,而动态控制AssetBundle的依赖关系是实现资源动态加载和更新的重要步骤。以下是一种常见的方法来实现动态控制AssetBundle的依赖关系: 1. 创建AssetBundle:首先,你需要创建和打包AssetBundle。你可以使用Unity的BuildPipeline.BuildAssetBundles方法来生成AssetBundle文件,并且可以指定资源及其依赖项的路径。 2. 加载主AssetBundle:在运行时,你需要加载主AssetBundle,这是整个资源加载的起点。你可以使用AssetBundle.LoadFromFile或AssetBundle.LoadFromMemoryAsync等方法来加载主AssetBundle。 3. 加载依赖项:一旦主AssetBundle加载完成,你可以通过AssetBundle.GetAllDependencies方法获取它的所有依赖项的名称。然后,你可以使用AssetBundle.LoadFromFile或AssetBundle.LoadFromMemoryAsync等方法来加载这些依赖项的AssetBundle文件。 4. 加载资源:当所有依赖项的AssetBundle加载完成后,你可以使用AssetBundle.LoadAsset或者AssetBundle.LoadAssetAsync等方法来加载资源。这些资源可以是场景、模型、纹理等。 5. 卸载AssetBundle:一旦你加载了所需的资源,你可以使用AssetBundle.Unload方法来卸载不再需要的AssetBundle。但要注意,如果你还在使用该AssetBundle中的资源,那么卸载后将无法访问这些资源。 通过以上步骤,你可以实现动态控制AssetBundle的依赖关系,实现资源的灵活加载和更新。当你需要更新资源时,你可以重新构建AssetBundle并替换旧的AssetBundle文件,然后再次按照上述步骤加载新的AssetBundle即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值