基于Unity YooAsset自动化资源管理框架,附源代码

源代码地址在最后,非常感谢你的观看

1.繁琐的内存管理,在C++时代对内存管理需要new 和 Delete相对应,Delete之后还需要把指针置空,不然会导致内存泄漏或者野指针的问题。

2.市面上普遍的资源管理采用Index计数方式管理,当计数为0的时候就会在内存不足或者特定的地方释放内存比如场景切换。

问题:Index计数方式过于繁琐,需要资源加载和释放完全对应,不然就会有内存泄漏风险。

思考:采用引用计数方式来处理内存释放,当引用数据为Null的时候,释放这个内存。

实践:

环境:Unity 2022.3.62

YooAsset版本:2.3.16

1.点击加载资源,我们可以看到YooAsset的AssrtBundle里面已经有多条加载到内存的数据:

2.我们点击卸载资源,会发现YooAsset的资源已经全部被清空了。

3.原理和核心代码,通过传入GameObject的引用,来保持资源的存活,当这个资源的GameObject的引用不存在的时候,就判定这个资源可以释放了。

cs 复制代码
 public async void LoadAssetAsync<T>(string path,GameObject refObj,Action<T> call)where T : UnityEngine.Object
    {
        AssetHandle assetHandle = _assetHelper.Package.LoadAssetAsync<T>(path);
        await assetHandle.Task;
        if (assetHandle.AssetObject == null)
        {
            Debug.LogError($"资源加载错误LoadAssetAsync:{path}");
            return;
        }

        if (!_autoRefData.TryGetValue(path, out ResAutoRefData resAutoRefData))
        {
            resAutoRefData = new ResAutoRefData(assetHandle);
            _autoRefData.Add(path, resAutoRefData);
        }
        resAutoRefData.RefObj.Add(refObj);
        T asset = assetHandle.AssetObject as T;
        call?.Invoke(asset);
    }

4.释放资源的代码(可以看到只检测了GameObject被释放的资源):

cs 复制代码
 //释放引用计数为0的资源
    public async UniTask UnloadAsset()
    {
        //因为GameObject销毁是在本帧的最后阶段才会消耗,所以要等待帧结束
        await UniTask.WaitForEndOfFrame();
        _removeHandle.Clear();
        foreach (string path in _autoRefData.Keys)
        {
            ResAutoRefData resAutoRef = _autoRefData[path];
            List<GameObject> refObjs = resAutoRef.RefObj;
            int refIndex = 0;
            foreach (GameObject refObj in refObjs)
            {
                if (refObj != null)
                {
                    refIndex++;
                    break;
                }
            }
            if (refIndex == 0)
            {
                resAutoRef.Handle.Release();
                _removeHandle.Add(path);
            }
        }

        //移除资源的加载
        if (_removeHandle.Count != 0)
        {
            foreach (string path in _removeHandle)
            {
                _autoRefData.Remove(path);
            }
        }
        UnloadUnusedAssetsOperation unloadUnused = _assetHelper.Package.UnloadUnusedAssetsAsync();
        await unloadUnused.Task;
    }

源代码地址:YooAssetAutoMemory: 基于Unity YooAsset自动化资源管理框架。

相关推荐
cui__OaO34 分钟前
Linux驱动--驱动编译
linux·运维·服务器
Q16849645151 小时前
红帽Linux-进程、ssh、网络、软件包、文件系统
linux·运维·网络
ℳ₯㎕ddzོꦿ࿐1 小时前
Docker 环境下 Paperless-ngx 中文增强版部署实战
运维·docker·容器
南烟斋..2 小时前
嵌入式系统(51单片机)核心外设详解:UART通信与DS18B20温度采集
linux·运维·网络
e***98572 小时前
跨平台虚拟机网络故障排查指南
运维·网络
重生之绝世牛码3 小时前
Linux软件安装 —— SSH免密登录
大数据·linux·运维·ssh·软件安装·免密登录
AI殉道师3 小时前
Vercel 重磅发布 agent-browser:AI Agent 浏览器自动化的新纪元来了
运维·人工智能·自动化
REDcker3 小时前
Puppeteer 与 Selenium 对比分析
爬虫·selenium·自动化·浏览器·puppeteer
计算机C9硕士_算法工程师3 小时前
基于深度学习风力叶片缺陷检测系统 无人机自动巡检风电场 - 风电运维智能诊断平台 - 缺陷生命周期追踪系统
运维·深度学习·无人机
Kiyra3 小时前
阅读 Netty 源码关于 NioEventLoop 和 Channel 初始化部分的思考
运维·服务器·前端