头图

下载AssetBundle的Mono内存问题

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(原群已满员)

UWA官网:[链接]

27 声望
12 粉丝
0 条评论
推荐阅读
MeshRenderer如何使用GPU Instancing的材质球正常合批
1)MeshRenderer如何使用GPU Instancing的材质球正常合批​2)关于AssetBundle加密,如何重新实现LoadFromFile接口3)移动端开放世界类型游戏中选择动态阴影技术以及优化方案组合4)Unity导出Gradle工程,如何防止...

侑虎科技

封面图
【golang】内存分配详解
使用span机制来减少内存碎片,每个span至少为一个页(go中的一个page为8KB),且大小为页的整数倍,每一种span用于一个范围的内存分配需求. 比如16-32byte使用分配32byte的span, 112-128使用分配128byte的span.

去去10022阅读 5.6k

年度最佳【golang】内存分配详解
这篇文章主要介绍Go内存分配和Go内存管理,会轻微涉及内存申请和释放,以及Go垃圾回收。从非常宏观的角度看,Go的内存管理就是下图这个样子,我们今天主要关注其中标红的部分。友情提醒:文章有点长,建议先收藏...

去去10023阅读 3.9k评论 2

Redis分布式锁的实现
很多新手将 分布式锁 和 分布式事务 混淆,个人理解:锁 是用于解决多程序并发争夺某一共享资源;事务 是用于保障一系列操作执行的一致性。我前面有几篇文章讲解了分布式事务,关于2PC、TCC和异步确保方案的实现...

KerryWu4阅读 6.8k评论 2

《Lua-in-ConTeXt》04:卡片
ConTeXt 输出的 PDF 文件,其页面尺寸默认与 A4 纸的尺寸相同。在今后,我可能要给出很多的排版示例。若给出排版结果的全貌,则 A4 尺寸太大了,会导致示例截图里的文字不够清晰。倘若能将页面尺寸设置为卡片大小...

garfileo阅读 987

《Lua-in-ConTeXt》01:Hello world!
ConTeXt,我不厌其烦地打出它的大小写字母,它的意思既非「上下文」,亦非「语境」或「环境」,而是 Text with TeX 的意思。这是荷兰人 Hans Hagen 为自己创造的一个 TeX 宏包而取的一个失败的英文名字。

garfileo阅读 927评论 2

《Lua-in-ConTeXt》02:ConTeXt 计算机
用于编写 TeX 源文件(例如 hello.tex)的任何一种文本编辑器,都可视为「ConTeXt 计算机」的终端。context 命令可将 TeX 源文件里的内容输出到 PDF 文件,于是可将 PDF 文件视为 ConTeXt 计算机的显示器。

garfileo阅读 893

UWA官网:[链接]

27 声望
12 粉丝
宣传栏