关于memory:下载AssetBundle的Mono内存问题

6次阅读

共计 3397 个字符,预计需要花费 9 分钟才能阅读完成。

1)下载 AssetBundle 的 Mono 内存问题
​2)Unity 2019 运行时获取 Hierarchy 上预制体资源门路
3)多个 Submeshes 模型合并后的显示问题
4)ToLua 中拜访 Time.deltaTime 为 0
5)CacheServer 莫名的断开连接


这是第 242 篇 UWA 技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫 10 分钟,认真读完必有播种。

UWA 问答社区:answer.uwa4d.com
UWA QQ 群 2:793972859(原群已满员)

Memory

Q:应用协程 +UnityWebRequest 下载 Bundle 时调配的内存开释不掉。

下载步骤如下:
1. 应用协程 +UnityWebRequest 下载 Bundle;
2. 应用 BinaryWriter 将 UnityWebRequest.downloadHandler.data 的数据写入机器;
3. 调用 UnityWebRequest 的 Dispose 函数;
4. 调用 Resources.UnloadUnusedAssets(),UnityWebRequest.ClearCookieCache() 和 System.GC.Collect()。

下载每一个 Bundle 都会执行如上流程,然而 Profiler 调试真机发现,调配的内存无奈开释,会把 Mono 内存越撑越大,请问大家遇到过这种状况吗?

A:之前遇到过相似的问题,题主能够参考一下,咱们应用的 Unity 版本是 2018.4.31。

不论是之前的 WWW 还是当初的 WebRequest,都是应用的其成员 DownloadHandler 进行下载。当你拜访“.data”属性时,其实拜访的是一个“GetData()”函数的包装,这个函数返回的是一段 native-memory data buffer 的拷贝,这也是问题的根结所在。

第一个能够优化的点就是缩小“.data”的应用,用长期变量缓存下来。
第二个就是替换 DownloadHandler,Unity 提供了多种 DownloadHandler,咱们过后是下载图片,所以用的是 DownloadHandlerTexture,看你的问题,能够试试 DownloadHandlerAssetBundle。

参考:https://docs.unity3d.com/ScriptReference/Networking.DownloadHandlerAssetBundle-ctor.html

感激 Joke@UWA 问答社区提供了答复

Editor

Q:美术心愿在编辑器运行的状态下获取场景 GameObject 实例对应预制体的门路,以前 Unity 2017 是能够通过 var pRoot = PrefabUtility.GetPrefabParent(go); return AssetDataBase.GetAssetPath(pRoot),获取运行时预制门路的。

最近降级到 2019 发现接口曾经更新,PrefabUtility.GetPrefabInstanceHandle(targetGameObject)、PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab) 等接口都不能在 Unity 运行的时候去获取 Hierarchy 外面的 GameObject 门路。

我问题外面的要害是运行状态,也就是点了播放,而后获取 Hierarchy 上预制的存储门路。PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab) 不点播放是能够获取,播放了只能获取 Project 上预制的存储门路。

A:PrefabUtility.GetNearestPrefabInstanceRoot:获取最近的预制体实例 Root。
PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot:获取预制体门路。

if (PrefabUtility.IsPartOfPrefabInstance(seletedGo))
{string prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(seletedGo);
} 

GetPrefabAssetPathOfNearestInstanceRoot 能够获取门路,“PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab)”这个接口传的不是 Prefab 局部,而是实例的。

如果不行,在 Editor 时,在它身上挂脚本或者别的形式建设映射,Runtime 下再拿。

感激静风霁 @UWA 问答社区提供了答复

Mesh

Q:求教下,我测试一个 Skinmesh 合并性能,发现当 Mesh 蕴含多个 Submeshes 时,合并胜利后,无奈渲染显示进去。

当测试的 Mesh 不蕴含 Submeshes 时,能够合并显示。难道 CombineMeshes 只能合并不带 Submeshes 的 Mesh?不晓得问题出在哪?有什么解决思路吗?

注:不论是应用“r.sharedMesh.CombineMeshes(combineInstances.ToArray(), false, false);”带上所有材质,还是“r.sharedMesh.CombineMeshes(combineInstances.ToArray(), true, false);”合并一张贴图材质,带多个 Submeshes 的模型只能合并无奈渲染显示进去。不带多个 Submeshes 的模型可能失常合并显示。

A:测试发现,须要对每个 CombineInstance 从新指定三角面,能力失常显示带多个 Submeshes 的模型。

如这段代码:

 foreach (SkinnedMeshRenderer smr in allSkineMeshList)
    {for (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++)
        {CombineInstance ci = new CombineInstance();
            ci.mesh = smr.sharedMesh;
            ci.mesh.triangles = smr.sharedMesh.triangles; // 这里从新指定

            ci.subMeshIndex = sub;
            ci.transform = matrix * smr.transform.localToWorldMatrix;
            combineInstances.Add(ci);
        }

    } 

感激题主牛头人不服 @UWA 问答社区提供了答复

Lua

Q:在 ToLua 中拜访 Unity 的 Time.deltaTime 始终为 nil,赋值给 Lua 变量也是 0。
PS:在 ToLua 拜访 Unity API 之前曾经进行过动态绑定,其余 API 都能够被 Lua 失常拜访。

为什么 ToLua 中拜访 Time.deltaTime 为 0?

A:Lua 的绑定必须写在 Lua 虚拟机启动之后:

感激题主 yxy@UWA 问答社区提供了答复

Editor

Q:客户端关上 Cache Server 面板测试 Connection 会发现连贯不上,而后点击一下服务器的控制台,Enter 一下会提醒:

而后客户端能力从新连贯,怎么感觉像是失去焦点的意思,这是什么起因呢?

A:Windows 在服务器的控制台右击设置属性 / 默认值“勾销勾选疾速编辑模式”。

感激 aladdin@UWA 问答社区提供了答复

封面图起源:VaSplineSnag
VaSplineSnag 是提供给 UE4 关卡设计师的样条曲线工具。
https://lab.uwa4d.com/lab/5b8627da02004fb65977efaf


明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在 UWA 问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官网技术博客:blog.uwa4d.com
官网问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com
官网技术 QQ 群:793972859(原群已满员)

正文完
 0