A1:这种情况下Active/Deactive的开销主要有几个方面: 1.C#层到Native层的穿梭调用速度比C#层内的速度慢。 2.UI元素的变化导致所在的Canvas变化,触发函数Canvas.SendWillRenderCanvases()与Canvas.BuildBatch()造成高耗时。 3.UI元素的网格顶点数组改变会造成堆内存分配,触发GC,导致耗时(不过对UI元素进行位置移动不会造成堆内存分配)。 因此,优化也可以从以下几点考虑: 1.在C#层设置变量来标识相应的GO处于Active还是非Active状态,避免对Active的对象进行SetActive(true),避免对非Active的对象进行SetActive(false)。 对Active进行SetActive(true)时,“底层”会进行判断,但调用的时候,就已经是从C#层调用底层,导致开销较高。在C#层判断好,就避免了让底层判断。 2.将要频繁变化的UI元素与不频繁变化的UI元素放在不同的Canvas中,减少UI元素变化时的耗时。 3.通过将UI元素的坐标移动到Canvas的范围之外的方法来显示与隐藏,避免SetActive的耗时以及SendWillRenderCanvases的耗时。 4.经测试,对Component进行enabled = false的操作比对GO进行SetActive(false)的操作耗时低。 5.通过添加CanvasGroup组件设置透明度的方式来进行显示与隐藏。
A2:最近做优化,也发现了这个问题,尤其是挂Image和TMPText的在SetActive的时候耗时更差。我准备从以下方面做优化: 1.对于挂UICanvas的直接修改Layer层。 2.对于不挂UICanvas的,改成挂CanvasGroup来控制Alpha. 这个地方有个麻烦的点。因为我们项目开了很久,让拼界面的同学去到需要控制的节点上挂CanvasGroup不太现实。在运行时动态挂组件,对性能有些担忧。所以打算改成运行时遇到修改Active的节点,到对应的Prefab下增加一个CanvasGroup控件,这样Prefab就补全CanvasGroup控件了。在正式上线之后,如果有遗漏不存在的,直接使用SetActive。 3.使用CanvasGroup方式有个缺点,只是改变了Alpha,依然会占有布局,所以父界面是Layout的,不能采用CanvasGroup。初步计划是对比SetScale0和SetActive的耗时,两者应该都会引起重绘。
A:占用包体的大小和在Editor下的Preview界面看到的大小是两回事。 Preview界面看到的大小是ASTC或者ETC2格式的资源的大小,而打包后,会对资源进行进一步的压缩(LZ4或LZMA)。只能说明ETC2压缩成LZ4后占用的包体大小确实比ASTC压缩成LZ4后占用的大小更小,至于原因就要看具体压缩算法的实现了。 可以用AssetBundle来验证,如果打AssetBundle包时选择NoCompression,那么确实ASTC格式的比ETC2格式的AssetBundle包更小。如果选择LZ4或LZMA压缩,那么ETC2格式的AssetBundle包比ASTC格式的AssetBundle包要小。
A1:在PhotoShop中针对PNG并没有透明通道这一说。导出也只能导出RGB3个通道。想要修改PNG像素的透明信息需要用到蒙板。 你和美术同学说“这块的信息画在蒙版上,黑透白不透”,他就明白了。
A2:选TGA美术比较好处理,也不用关心PNG那几种格式的区别,PhotoShop里也不用处理Alpha的事,毕竟在引擎里都要根据不同平台进行压缩处理。不在乎工程大小的情况下,流程更方便才是关键。
A1:是不是JNI调用次数太多了?我之前试过,有个腾讯语音的API一直在调用JNI,运行到一定时间后就崩溃了,日志好像跟你一样。
A2:应该是AndroidJavaClass和AndroidJavaObject只频繁New没调用Dispose导致的。
A3:参考以下信息: 2019.4.21f1 Release Notes Fixes Android: Fixed Java local reference leaking when using AndroidJavaClass/Object. (1283209) 在 https://unity3d.com/unity/whats-new/2019.4.21 的Fixes里。
A1:AssetBundle.LoadFromMemory 1.使用UnityWebRequest下载的AssetBundle资源并且使用后不存到本地; 2.有加密需求的AssetBundle资源。 AssetBundle.LoadFromStream 1.有加密需求的AssetBundle资源(内存值理论上比AssetBundle.LoadFromMemory小); 2.Android下需要Copy出StreamingAssets目录外,创建流。
A2:当资源有加密需求时,可先把AssetBundle读取到内存当中,进行解密后再调用该AssetBundle.LoadFromMemory进行加载。该方法消耗的最大内存量将至少是AssetBundle的两倍。可参考《AssetBundle的原理及最佳实践》。 AssetBundle.LoadFromStream可进行流式加载,不需要将AssetBundle全部读到内存中再解密、加载,而是可以通过每次像Buffer中读一部分,解密一部分的方式进行加载,不会多占用一份很大的内存。如果使用该接口,需要自定义一个继承FileStream类,然后在Read和Write方法内对Byte数组进行异或加密解密处理。 具体用法可参考:https://www.xuanyusong.com/archives/4607
您需要 登录 才可以下载或查看,没有账号?立即注册
使用道具 举报
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )
GMT+8, 2024-11-15 08:29 , Processed in 0.091522 second(s), 26 queries .
Powered by Discuz! X3.5 Licensed
© 2001-2024 Discuz! Team.