UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技 - mono
type: channel
link: https://blog.uwa4d.com/tag/mono/
items: ProtoBuf-net Serializer.Serialize产生大量的GC
items: 子线程GC导致主线程函数耗时较高的问题
items: DrawInstance和完全不做合批情况下的性能差异
items: 多个相机分别实现各自屏幕后处理的问题
items: 开启Allow unsafe code的影响
items: 如何远程更新Addressable随包打进的游戏资源
items: 关于Texture2D Crunched压缩格式
items: 一个高效研发的制胜之道 | UWA GOT Online功能说明
items: 重要消息 | UWA 在线性能测评支持IL2CPP！
items: 开发WebGL项目，你需要了解这些...

ProtoBuf-net Serializer.Serialize产生大量的GC
type: item
date: 2022-03-09T03:48:00+02:00
description: 1）ProtoBuf-net Serializer.Serialize产生大量的GC ​2）如何快速在工程代码中每个函数注入自己想要插入的代码 3）Unity设置IL2CPP导出的Mac平台的Xcode工程中，如何通过Object-C代码反调Unity侧的C#代码 4）ShaderGraph生成的Shader在UGUI上使用的问题 这是第289篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Mono Q：在我们游戏中有使用到ProtoBuf的序列化，在查找性能问题的时候看到序列化的函数产生了大量的GC，如下图： A：可以参考《Unity3D游戏GC优化总结---protobuf-net无GC版本优化实践》。 感谢lanyt@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/621f2a12d83cff4676f5b924 Script Q：如何快速地在工程代码中的每个函数注入自己想要插入的代码？有说借助Mono Ceil的，还有一些库没有开源，所以想请问有没有其他方面的资料可以参考？ A：可以参考《使用Mono.Cecil实现IL代码注入》。 感谢羽飞@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6220e17380139e0c1f157aae Script Q：在iOS平台下，IL2CPP导出的Xcode工程中Object-C调用Unity方法是通过SendMessage实现的： 请问在Mac平台下IL2CPP方式导出的Mac工程，如何通过Object-C代码反调Unity侧的C#代码？也是通过SendMessage的方式吗？但是我没找到相关的接口。 A：用SendMessage是可以实现的，但是效率不好。可以参考我这个Object-C回调Unity。把你需要的接口，写成函数指针，在Object-C里注册，需要时做回调。 可以参考《Unity与Object-C交互》。 感谢廖武兴@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6215fcede7172c2775f76e56 Shader Q：我用URP 10.4.0和Shader Graph10.4.0建立了一个用于UGUI Image的Shader，它能在PC上正确运行，但是在手机上UV就错误了，如下图： 如下图，这样直接连一个简单的Tex2D就会出现，ShaderGraph也如下图连接： 我使用Unity 2022 URP13.1.6 SG13.1.6再次建立同样的ShaderGraph Shader在手机上是正确的，但是我暂时没有办法更换Unity版本。 A：可以参考这个视频的做法，应该是不能直接把ShaderGraph生成的Shader直接用到UGUI上的，需要做一些调整： https://www.youtube.com/watch?v=RxW7_qgkXPo 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6221ec0d80139e0c1f16e5e2 封面图来源于：Protobuf-net Optimization Protobuf-net无GC优化版本，另外还提供了一些无GC自定义数据结构，以及对Unity 3D中C#代码的各种无GC使用方式测试。 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com UWA学堂：edu.uwa4d.com 官方技术QQ群：793972859（原群已满员）

子线程GC导致主线程函数耗时较高的问题
type: item
date: 2021-11-10T04:18:00+02:00
description: 1）子线程GC导致主线程函数耗时较高的问题 ​2）升级Unity大版本后，Text颜色修改问题 3）清除增量式GC导致的Mono堆内存泄漏问题 4）多Pass合批优化问题 这是第274篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Rendering Q：在主线程中有非常多的卡顿，从UWA的报告中看到很多异常的高耗时，请问可能是什么原因造成的？ A：像上面这样的频繁卡顿，且卡顿函数种类非常多的情况，应该是子线程分配了非常多的堆内存，导致子线程GC，从而卡住了主线程。当GC的时候，主线程可能会处于各种阶段，因此对应阶段的函数耗时就会包括等待GC的耗时。可以从UWA的Mono报告中查看是否有子线程分配了大量的堆内存，通常是由这种（Thread）打头的子线程函数的分配导致的。 感谢han@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6180e0f28f8c834241fd6930 UGUI Q：从Unity 4.6.9f1升级到Unity 2020.3.2.f1c1。首次Unity升级之后UI的Text颜色修改是正常。当运行一次之后，所有的Text颜色都无法修改了。就算新创建一个新的Text也无法修改。 A：会有多余的UI-Default和UI-DefaultFont这两个Shader，删除它们，然后重启Unity就好了。 感谢芝麻青豆角@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/6185085fd8413e18eb034520 Mono Q：最近在研究Mono堆内存时，发现一帧内分配多次较大内存，会导致内存无法被回收。 过程如下： 在同一帧内调用三次分配100MB内存的方法，分配内存的变量都是在各自的作用域，在这之后调用GC.Collect()。发现有较大几率出现100MB或者200MB无法被回收的Mono堆内存。经过排查之后发现取消勾选Incremental GC之后，内存就能完全被收回。 我推测是每次申请内存的时候会执行一次GC，清除上一次分配的内存，但是由于使用增量GC，无法在本帧完成回收工作。再下一次GC的时候，第二次GC的回收内容被重置了，导致第二次的GC需要被回收的内存就泄漏了。 不知道我这么理解是不是对的，希望大佬们解惑。同时希望大佬告知有没有办法清除这部分内存。 测试环境： Unity 2019.4.15c1 Unity 2020.4.15f2 测试平台： 安卓 Mono 以下为测试代码： using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Profiling; public class TestMonoMemory : MonoBehaviour { void Do() { CallBack01(); CallBack02(); CallBack03(); } public void CallBack01() { List<int> i = new List<int>(1024 * 1024 * 100 / 4); //CallBack02(); } public void CallBack02() { List<int> i = new List<int>(1024 * 1024 * 100 / 4); //CallBack03(); } public void CallBack03() { List<int> i = new List<int>(1024 * 1024 * 100 / 4); } public string text; private void OnGUI() { GUILayout.Label("Allocated Mono heap size :" + Profiler.GetMonoHeapSizeLong() / (1024 * 1024) + "MB"); GUILayout.Label("Mono used size :" + Profiler.GetMonoUsedSizeLong() / (1024 * 1024) + "MB"); GUILayout.Label("Total Reserved memory by Unity: " + Profiler.GetTotalReservedM…

DrawInstance和完全不做合批情况下的性能差异
type: item
date: 2021-01-25T10:25:00+02:00
description: 1）DrawInstance和完全不做合批情况下的性能差异 ​2）UWA报告中检测出工程没有的资源 3）精灵设置九宫后，如何不在界面中显示出来 4）关于AssetBundle资源的卸载问题 5）Total Mono突然上涨的原因 这是第236篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Rendering Q：我做了个测试，环境：Unity 2019.4.15 ，机型：小米5X，绘制1000个物体（顶点数>300，不动态合批），测试顺序是：Unity默认渲染（20 FPS）–>Update中通过Graphics.DrawInstance（16.5 FPS）–>通过CommandBuffer实现的DrawInstance（21.5 FPS），对于第二个测试DrawInstance性能反而降低了不太理解，有大佬帮忙解答吗？ 图片和测试工程可通过以下链接下载： 链接：https://share.weiyun.com/ZFOlW1of 密码：ip37rr A：1.Instancing耗时更高主要原因还是GPU压力比较大，见下面的测试案例： 测试1：1000个物体（顶点数88，关闭动态合批） Default：子线程Camera.Render（14.59 ms）、Gfx.PresentFrame（3.94 ms） Instancing：子线程Camera.Render（7.1 ms）、Gfx.PresentFrame（4.70 ms） 测试2：1000个物体（顶点数1278） Default：子线程Camera.Render（15.02 ms）、Gfx.PresentFrame（9.01 ms） Instancing：子线程Camera.Render（8.21 ms）、Gfx.PresentFrame（19.15 ms） Instancing是能够明显降低CPU渲染（Camera.Render）耗时的，但GPU调用DrawInstanced()比Draw()的性能似乎差一些，导致CPU端等待耗时较高。所以Instancing总体帧率有所下降主要是GPU的压力较大导致的。 2.如下图Graphics.DrawMeshInstanced在Update中每帧调用存在脚本耗时明显DrawInstancing更高（在Update中准备相关DrawInstance参数），Demo渲染的是静态物体，使用CommandBuffer实现DrawInstancing可优化这部分耗时，同时在Update中的逻辑也会有New XXX[]数组这样的Mono堆内存频繁的分配，也会有GC影响（这部分影响较小）。 结论：Instancing可以降低CPU渲染耗时，但GPU API性能会有所降低，帧耗时还是受到CPU渲染耗时及GPU耗时的综合影响，不同的机型可能表现的会有所差异。 Instancing的使用：推荐绘制大量静态物体时使用CommandBuffer的实现，例如草海之类的。 感谢羽飞@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/60095ef310a17c6c2b09dc04 Texture Q：请问一下：性能报告中，RGBA32的图片有一些在工程中没有，但是在报告中却体现，请教一下这些是哪里产生的？ A：截图中的Background、UIMask、UISprite是由UGUI中默认的UI元素引入的，如下图中的ScrollView： UnityNormalMap这个是由于Shader中的纹理使用Bump作为默认的值，但是在材质球中又没有给这个纹理赋值导致的。对于这种空纹理的资源，在UWA本地资源检测中是可以检测出来的。 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/600a812910a17c6c2b09dc31 UGUI Q：导入一张171*41的图片，设置完九宫信息后创建UI图片。然后设置图片宽高为0，并设置图片模式为Sliced。但是还是能看到图片显示出来了。个人感觉上是UV计算错误了。如果切换到Simple则图片正常不显示。请问大佬这是什么原理？ 测试工程可在原问答下载（版本：Unity 2018.4.23） A：这个和九宫格图片的实现原理有关，可以看看下面这个图片： 当你选择Sliced模式，他有一个最小的绘制区域，也就是四个角：1、3、7和9，必须绘制出来。当你设置的Rect大于1、3、7、9四个角组成的区域时，那么…

多个相机分别实现各自屏幕后处理的问题
type: item
date: 2021-01-13T16:26:00+02:00
description: 1）多个相机分别实现各自屏幕后处理的问题 ​2）怎么查看子线程中的GC Alloc 3）Mesh组件的世界坐标 4）绘制的Mesh丢失了Unity自带的Keywords 5）AssetDatabase V2和V1的核心区别 这是第235篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Rendering Q：游戏中有多个相机，每个相机有自己的后处理效果。但是发现Depth越大的相机OnRenderImage传过来的图像越小于这个Depth所有相机的叠加图像，这样就没法实现各自的后处理效果，有什么方法可以解决吗？ A：经过测试，给Camera赋值RenderTarget，那这个相机上的OnRenderImage就只会对这个RT起作用。 使用这种方式，对不同的Camera加不同的OnRenderImage。最后需要一个额外的相机将这些RT合在一起，在这个额外的相机里面，可以渲染一个Canvas，里面用多个RawImage来将之前的RT叠在一起。 下图中，球和天空盒是场景相机渲染的，相机渲染到RT1，文本是UI相机渲染的，相机渲染到RT2。 第一个相机OnRenderImage里面颜色反一下，第二个相机的OnRenderImage里面变成灰度图。从下图可以看到这两个效果是相互独立的。 最后用CombineCamera画一个Canvas，里面有2个RawImage，RawImage里面的Texture分别使用那两个RT就可以了，如下图： 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5ffd0b2910a17c6c2b09d98c Mono Q：我把一些大计算量的东西放到了子线程中，现在想看下有没有GC Alloc，但是没找到像Profiler.BeginSample/Profiler.EndSample这样的方法，看不到子线程中的GC Alloc，只能看到时间开销。请问要怎么才能看到子线程中的GC Alloc呢？ A：目前新版本的GOT2.3版本已经支持了。 《多线程统计 | GOT Online新功能上线》 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5e575ef386a3954891983a38 UGUI Q：Mask组件的世界坐标传给了Shader，然后要把模型空间的Vertex转到世界空间进行对比。 把Mask的四个角的坐标通过GetWorldCorners这个接口获取到传给Shader， 然后将特效的Vertex转换到世界空间中作比较。但是效果看起来这个转换的值好像不太对，我的渲染模式是Overlay。 A：我把Render Mode改成Camera就行了，应该是在Overlay下GetWorldCorners获取到的值不正确。 感谢题主方星@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5ff9606310a17c6c2b09d94e Rendering Q：使用CommandBuffer.DrawRenderer绘制的Mesh会丢失Unity自带的Keywords，导致ShadeSH9计算的结果不对。（版本：Unity 2019.2.0f1） 正常渲染： CommandBuffer.DrawRenderer： A1：光照处理阶段，CommandBuffer的内容还未产生，所以也就不会有球谐和屏幕空间阴影的内容了。 感谢李星@UWA问答社区提供了回答 A2：测试后发现，可以使用EnableKeyword来强行开启Keyword。但是会遇到环境光渲染不出来的问题。 正常的渲染如下： 环境光渲染不出来，如下： 虽然Keywords是完整的，但是环境光还是没渲染出来，原因是SH的系数出问题了，具体解决方案可以参考： https://github.com/keijiro/LightProbeUtility 使用如下的代码可以让这个Cube和普通的渲染方式产生相同的渲染结果，但是需要使用CommandBuffer.DrawMesh的方式。 public class TestCommand : MonoBehaviour { public MeshRenderer rend; public Mesh mesh; CommandBuffer cb; MaterialPropertyBlock block; Materi…

开启Allow unsafe code的影响
type: item
date: 2020-10-19T07:14:00+03:00
description: 1）开启Allow unsafe code的影响 ​2）Unity线性空间下，PhotoShop制作半透明图片，制作带外发光、内发光的图层如何正确导出 3）Unity中实现完善的暂停机制 4）RenderPipelineManager.DoRenderLoop_Internal的堆内存优化 5）Unity 2020版本中ARBackgroundRenderer和ARRenderMode的相应替代类 这是第223篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Script Q：最近项目引进几个插件，以及学习别人的插件，代码中用到了unsafe关键字，需要再project settings中勾选Allow unsafe code，之前知道一点是不勾选最好，但是勾选以后到底哪里不好也忘了，也没有勾选之后上线来验证，所以问问大家，是否应该勾选，以及勾选之后有何影响？ A：勾了没什么实际上的坏处，只是由于.net当初设计的时候是不鼓励使用unsafe代码的，所以在编译器默认设置这个门槛，鼓励大家尽可能使用安全的代码（也就是不要直接操作原生内存地址）。 但是，很多高性能的C#代码为了最大限度地高效访问内存，不可避免要用unsafe，只要保证unsafe代码被限制在较小的范围并严格测试保证不会出内存访问错误，对整个工程来说就不是大问题。 感谢招文勇@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5f8820039424416784ef27cb Texture Q：大家好，因为项目是PBR项目，所以Unity使用线性空间，现在在制作UI的时候，带透明通道的图片，混合时候就会出错。 我们前后试了几种方法： 1. 改PhotoShop的工作空间为线性的，定义Gamma为1.0： 2. 单独改用灰度系数混合RGB颜色：1.00，这样大部分情况下，Unity中效果PhotoShop中效果就是一致的： 3. 改Unity渲染管线。 以上方法都有一些局限和问题。 1. 普通不透明图层有些渐变效果无法绘制，因为线性空间下的暗部颜色精度不够； 2. PhotoShop制作带外发光、内发光的图层合并之后会错误： 3. 因为用的还是内置Forward管线，影响太大，低端机效率低下，暂不考虑。 我们最终采用的是第二种，美术还是在Gamma工作空间作图，只是图层混合采样。 最后想问下大家，针对线性空间下的半透明图层如何导出？ 或者有没有什么办法能处理这种外发光、内发光图层问题？ A1：目前公司项目都采用Linear方式，美术直接修改PhotoShop设置，出图过后，在Unity中测试，能与原图是一个色彩，之前也尝试过其他办法，如Shader修正，但是都有一定的问题，目前采用的这种方案，暂未发现问题。 感谢范超@UWA问答社区提供了回答 A2：用下图的配置，在PhotoShop CC 2019里试了下，只要不合并图层，直接导出png，再放到Unity中就没有问题。另外如问题中的例子，只要从下向上合并图层（带着背景），最终结果就没问题。可能是PhotoShop的Bug。 就我和美术了解的情况，他们很少合并图层。一般导出就是把不需要的图层隐藏了。所以这种情况应该是可以避免的。 感谢张首峰@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5f8129c29424416784ef25a1 Script Q：目前使用TimeScale=0来暂停游戏，但是在UI上不想让特效和动画暂停，而在某些战斗场景，只希望暂停一部分逻辑。如果把TimeScale=0，就要处理ParticleSystem、TrailRenderer、Spine动画等组件，特别是TrailRenderer和Spine都需要修改源码。如果不用TimeScale=0， 是不是就要在框架层就处理好各模块的更新逻辑？ A1：常规的做法确实就如你说的，不用TimeScale=0，各个地方去实现暂停，然后统一管理。 感谢邓永健@UWA问答社区提供了回答 A2：可参考这篇文章：《Unity Chronos - Time Control 时间控制器》 感谢黄程@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5f812d769424416784ef25a4 Mono Q：项目采用了URP，用UWA进行了初步测试，发现RenderPipelineM…

如何远程更新Addressable随包打进的游戏资源
type: item
date: 2020-07-14T12:08:00+03:00
description: 1）如何远程更新Addressable随包打进的游戏资源 ​2）Unity内存机制与安卓内存机制的关系 3）UWA报告中的GPU渲染信息统计 4）如何采样不同纹理压缩格式的时间 5）如何去掉每帧的GC 这是第211篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Addressable Q：我们新项目想用Addressable Asset System。我这几天看了一下，有个问题想请教一下：AAS通过Build and Load Paths设置local/remote决定Group中的资源随包/远端下载。那么我想在远端更新local方式的资源（即随包打进StreamingAssets中的资源）该怎么操作？ A：Local打包方式的Group设置Cannot Change Post Release，两个属性bundlename设置成FileName，取消bundle的CRC，这样再Check/Build之后就可以做到增量更新了。Addressable会把改变的部分生成到一个新的Group中，这个Group会默认设置成remotebuild/load 。这样就做到增量更新了。 感谢题主柚子爱爸爸@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5ee9d9725d07d80acd26241c Memory Q：Unity内存机制与安卓自身的内存机制有什么关系？我目前的理解是安卓操作系统基于Linux内核，所以自己有本身的内存管理机制；而java VM是为了让一些应用可以运行在安卓平台上而建立的一种跨平台机制。相当于在安卓系统上开了一个虚拟机，应用运行在虚拟机的环境中。同理，Mono和IL2CPP也是另一种虚拟机，也会运行在安卓操作系统上，但是也有着自己本身虚拟机的内存管理机制，也就是说Unity的内存管理机制实际上就是Mono或者IL2CPP的内存管理机制。 想了解下我的理解对吗？虚拟机的管理机制和安卓系统的管理机制有什么样的关联呢？任何相关的回答都不胜感激，谢谢！ A：可以参考： 《浅谈Unity内存管理》——视频 https://www.bilibili.com/video/av79798486/ 《浅谈Unity内存管理》——猫冬夏的笔记 https://www.notion.so/Unity-f79bb1d4ccfc483fbd8f8eb859ae55fe 感谢俞顺捷@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5f02890dc6123f2e0df5b3ae Rendering Q：URP项目GPU渲染信息统计问题：看情况是统计到逻辑代码里了，这个后面会区分出来吗？ A：CPU耗时和GPU耗时是完全不同的两码事。虽然最终渲染是在GPU端进行，但是CPU端也需要做很多事情的，比如提交Draw Call。以不透明渲染来说，常见的是Render.Mesh,Batch.DrawStatic这些Draw Call的提交，再比如MeshSkinning.Render，Culling等，这些都算在Camera.Render的耗时里面。 在使用了SRP的情况下，与Camera.Render相对应的函数叫RenderPipelineManager.DoRenderLoop_Internal()，这里面的耗时也都是CPU端的耗时，建议题主通过UWA线上的真人真机测评服务来查看更为具体的耗时分配。 题主截图中的GPU耗时为0，可能是因为使用了Vulkan，也可能是因为某些GPU型号问题（一般出现在华为手机上），但这个跟CPU的耗时都没有关系的，也并不是GPU的耗时统计到CPU逻辑代码里面去了。 感谢Xuan@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5f02e4a2ade17d6115427bb2 Texture Q：有什么方法可以知道采样不同纹理压缩格式的时间吗？想了解下对于ETC2 ETC、ASTC采样所消耗的时间，能够具体量化吗？ A：我理解只要是硬件原生支持的贴图格式，采样的时长应该没什么差别吧，毕竟都是硬件解压到显存中进行。 更可能产生差异的是大小不同导致的传输时间和命中率上的差异，比如ASTC通常优于RGBA的原因就是对于带宽占用小，Cache命中率高。 可能整体看更好，当然如果要去追究采样消耗，可能通过一些GPU Profile统计Samp…

关于Texture2D Crunched压缩格式
type: item
date: 2020-06-22T11:47:00+03:00
description: 1）关于Texture2D Crunched压缩格式 ​2）Unity自身GC和.NET的GC如何协调工作 3）关于环境光照球面坐标映射2D贴图UV的某算法的疑问 4）iOS审核dlopen、dlsym风险 5）Unity 2018.4在iOS上压缩贴图用的是哪个可执行文件 这是第208篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） Texture Q1：关于Texture2D的压缩格式设置上，想问一下大家有没有Crunch ETC2 压缩格式的上线经验。效果如何？ A1：当时是使用的Unity 4.7，后来翻了5.6的源码移植。2017的算法有了更多的优化。为了解决包体大小的问题，曾经在某上线项目中，将Crunched ETC2功能移植到了Unity早期的版本中。 使用Crunched ETC2压缩后会降低包体的大小，但同时会增加运行时解压缩的时间消耗，总体来说效率影响是比较可控的。不同的贴图使用Crunched ETC2会有不同的压缩比，于是对于一类贴图批量控制贴图格式将达到更好的压缩性价比。 当时我们针对部分类型的帖图进行了Crunched ETC2的压缩，测试下来的效果是默认开启Crunched ETC2整体包体可以优化百分之十左右。其中在三星 Note3上，单张512开启10级Mipmap，解压时耗大约在2ms左右。 使用最新的Unity引擎启用Crunched后将获得更好的效率（Unity本身也持续有优化。貌似之前Crunched的作者已被官方收编）如果对包体大小要求较高，建议可以大胆尝试。 Q2：目前用Crunch ETC2算法压缩在安卓平台下一个2048*1536的图可以压到342KB。压缩比例很高，使用的版本用的Unity 2017还是更早？ A2：当时是使用的Unity 4.7后来翻了5.6的源码移植。2017的算法有了更多的优化。 感谢康斯特@UWA问答社区提供了回答，欢迎大家转至社区交流： https://answer.uwa4d.com/question/5eec64f9ea02f0538ce31716 Script Q：Unity有自己的GC，.NET也有自己的GC，两者在游戏运行的时候，是如何协调工作的？ A1：提出这个问题之前，先要搞清楚一个问题：Unity与Mono和.NET三个概念之间的的关系。 维基百科： .NET框架（英语：.NET Framework）是由微软开发，一个致力于敏捷软件开发（Agile Software Development）、快速应用开发（Rapid Application Development）、平台无关性和网络透明化的软件框架。 .NET Framework是一个软件框架，可以理解为对一系列结构和功能的期待。不是一个具体的某个软件。最初有一段时间，.NET框架只能在Windows平台上运行。 Mono是.NET运行时和开发库的实现版本，为C#脚本提供一个编译器和运行的虚拟机（CLR）。Mono的初衷是：(1)使微软.NET应用可以跨平台运行 (2)支持.NET在Linux上使用。Mono比.NET Core支持更多的平台（如：Linux、FreeBSD、Unix、Mac OS X和Solaris）。 Unity引擎对跨平台特性有很大的需求，于是使用Mono提供C#等符合CLI规范的脚本语言的运行环境。 直观的理解参考下图： 总的来说，Unity驱动Mono，为C#等提供编译和运行的环境。而C#等脚本的GC便是由Mono的虚拟机提供的。 因此，题主说的Unity自己的GC，和.NET的GC，应该是一回事，也就是Mono的GC。（如有错误之处，希望大神指出） Ref: https://www.cnblogs.com/shanyou/p/4295163.html https://www.cnblogs.com/zhujinghui/p/3369217.html https://zh.wikipedia.org/wiki/.NET框架 https://en.wikipedia.org/wiki/Mono_(software) https://www.cnblogs.com/u3ddjw/p/10909975.html 上面忽略了Native层的内存垃圾，不过Native的垃圾回收不存在像Mono一样的自动回收机制。需要主动调用Resources.UnloadUnusedAssets()来触发。 感谢Prince@UWA问答社区提供了回答 A2：Unity里面的 C# GC是针对代码层的。Unit…

一个高效研发的制胜之道 | UWA GOT Online功能说明
type: item
date: 2018-12-20T06:53:00+02:00
description: 不管项目本身是否重度，性能调优永远是上线前的必经之路。优化性能，不仅需要足够深度的分析来定位问题瓶颈，也需前瞻性的保障措施来缓解后续的优化压力和性能风险。因此，我们推出了UWA GOT Online，并且很荣幸地在推出后得到不少朋友的积极反馈。 关于UWA GOT Online UWA GOT是UWA推出的本地性能测评工具，它方便研发团队在本地真机测试，并能在编辑器中搭建本地服务器查看性能数据。UWA GOT Online是基于其本地测评模式上的线上同步功能，研发团队可以将本地测评的数据快速同步到UWA官网，生成在线测评报告。 除了“本地化”和“快”这两大天然优势，我们目前提供了四大性能检测模式：总体性能检测、Mono堆内存分析、运行时资源检测和Lua性能分析来满足大家的优化需求，下面小编就带大家一一浏览。文末附上UWA GOT Online的使用攻略哦！ 以下是四大模式的核心功能和特色，点击对应的条目可以查阅详细的功能说明。 CPU性能检测 全方位的引擎模块剖析（渲染、物理、粒子、UI、动画和加载，一个都不能少） UWA API 提供（锁定你关注的性能细节，让其无处遁形） Mono堆内存检测 Mono具体分配详情（对代码堆内存的分配一目了然，还有贴心的倒序功能哦） Mono堆内存泄露定位（代码泄漏风险？用这个模式捋一遍就明了） 运行时资源检测 具体资源使用情况检测（详细展现主流资源的具体运行情况） 资源内存泄露定位（不同采样点随心比较，科学排查泄漏风险） Lua性能检测 LuaCPU性能测评 （深度、全面的调用堆栈，直接锁定性能瓶颈） Lua内存检测（无论是内存分配过大还是内存泄露，用它就对了） 凭借“本地化”和“快”两大天然优势，UWA GOT Online能让项目人员快速执行项目的测试需求，以更友好、更易用的展示方式呈现给开发者。同时，依托于报告中具有针对性的分析建议，研发/测试人员也能定期地对自己的项目版本进行性能跟踪，一旦发现某个版本上的某个重要性能指标出现了问题，就能及时反馈给研发团队进行完善和修复。 UWA GOT Online截图 项目的研发需要持续改善，而解决问题的最佳时机就是在我们看到问题的当下，从而极大减少后期的优化时间，降低后期堆积的性能压力的风险，并加快游戏的整体研发进度。 以上就是UWA GOT Online功能的不完全说明，更多功能欢迎大家登陆www.uwa4d.com，在“本地测试 / UWA GOT Online”中查看各个模式下的Demo报告。 UWA GOT Online使用攻略 1、我可以直接用UWA GOT Online吗？具体操作方式如何？ 首先你需要拥有一个灵活的本地化测评工具UWA GOT； UWA GOT Online的具体操作方式为：本地真机测试完毕后，将测试数据传输到UWA官网进行查看。 2、UWA GOT和UWA GOT Online功能上有哪些区别？ 配置还是很不一样的哦，后者包括更广度的检测模式/功能，包括Lua性能、CPU性能模块分析、性能简报、优化建议和版本对比等功能，具体可参见此处。 3、想试试看怎么入手？ 登录UWA官网的个人账号，选择“立即体验”即可开始试用。 4、UWA GOT Online具体效果如何？ 截止目前，我们收到不少团队的积极反馈，并获知该功能帮助他们改善了测试机制。 UWA报告Tips 性能简报—小白都能秒懂的定位方法！ 优化时间不充裕？快快让性能简报帮你抓重点！ 突然卡顿不知为啥，卡顿分析里有大秘密！ 解决疑难杂症必备：堆栈分析，从此开启专家把脉模式！ 重要引擎性能参数，把握项目健康的几个核心指标！ 内存过高，资源占用的几个大头要盯牢！ 粒子数量过高，看看是否都物尽其用了？ 特效复杂，使用Overdraw排查问题就对了！ Mali Counter 分析，高效定位发热、耗电现象 Timeline视图分析，直观显示卡顿的时序 Lua-Mono对象引用，解决Mono内存泄漏的顽疾 Shader解析耗时高，原来是冗余问题在作怪 资源实例化&激活，想要运行表现平滑，这个技巧不能少 Mipmap分析，优化纹理分辨率，每个像素用到刀刃上 自定义参数，随时把关重要参数走势 GC调用分析，GC耗时、调用频率一览无余 渲染模块性能分析，快速定位，一目了然！ Shader.CreateGPUProgram 优化分析，特别重点关注游戏战斗中的耗时！ Shader.Parse优化分析，优化Shader策略，避免重复加载卸载！ Unity卸载优化分析，场景切换时间太长，如何有效优化？ 物理模块优化分析，一招教你把耗时清零！ 网格内存优化，降低网格内存一二三，走你！ 纹理资源内存优化（一），纹理太大还是冗余？这些小技巧必备！ 纹理资源内存优化（二），优化缓存策略，巧妙降…

重要消息 | UWA 在线性能测评支持IL2CPP！
type: item
date: 2018-07-31T17:25:00+03:00
description: 今天推送一则重要消息！UWA在线测评在Android平台上增加了对IL2CPP的支持（iOS平台照常支持）。随着越来越多的Unity项目在该模式开发和打包，该支持将为大家的项目打包测试提供了极大的便利！ 目前，在UWA官网中下载到的最新版UWA SDK（版本号1.2.3）中，我们可以看到针对不同模式，分为普通（Mono）和IL2CPP两个版本，大家只需针对各自的开发模式进行对应的SDK集成即可。 从此不再为运行时的选择而烦恼，大家可以痛痛快快地出包提测啦！ 需要说明的是，IL2CPP 模式下，尚不支持以下模块的数据检测：资源管理、GPU 性能和堆内存测试。对于这些模块性能较为关注的开发者，建议尽可能用 Mono 模式发布提交，以获得完整的性能数据。

开发WebGL项目，你需要了解这些...
type: item
date: 2018-07-31T17:04:00+03:00
description: 这是第122篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间10分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群2：793972859（原群已满员） WebGL Q1：目前我们有一个采用Spine的2D项目需要转换成H5游戏，请问直接使用Unity开发WebGL的项目，性能上会有哪些注意事项呢？ 看题主的意思是想在移动设备上跑。我们项目（竞速类）曾尝试了直接用Unity 5转为页游版本，但是是运行在PC平台上的，手机上简单了解过别人的项目，当时得出的初步结论是在移动设备上中重度的3D性能扛不住，这个没有经过亲自验证。 我列下我们在Unity5转PC页游踩的坑供你参考下： 1）WebGL中不支持多线程和C#网络，可以用协程、Websocket代替； 2）我们有些协程用法写得有问题，在协程函数中用了While(1)这种死循环等待资源加载完成，在其它平台下没问题，但是在WebGL中会死循环，大概跟WebGL不支持多线程有关； 3）在游戏加载资源过程中，随着占用内存增大，偶尔会内存溢出，这主要是我们资源没有优化好导致的。我们在跟一个成熟的页游团队交流时，对方建议页游内存不要超过256MB，需要很细致地控制资源的加载和释放； 4）建议使用LZ4压缩格式，WebGL不支持多线程，LZMA压缩的Bundle会导致主线程解压缩时的卡顿； 5）单个资源体积不宜过大，建议控制在1MB以下，尽量做资源依赖打包，要不加载时间过长，很影响体验； 6）WebGL不支持中文输入，我们用原生的方式实现了中文输入； 7）PC端一些浏览器直接不支持，我们测试支持的浏览器有： Google Chrome 9+ 2.Mozilla Firefox 4+ Safari 5.1+(仅限Mac OS X操作系统，不包括Windows) Opera 12 alpha以及以上版本 IE9+，但是IE并不支持WebGL，不过你可以通过下载并安装IEWebGL这个插件 QQ 360 搜狗 8）资源如果没有实例化使用，在Editor下不会闪退，但是打出的PC包和导出的WebGL版本都会闪退。 感谢赵林@UWA问答社区提供了回答，欢迎大家转至社区进一步交流： https://answer.uwa4d.com/question/5b3a27bd3ab9166bb3e84927 堆内存 Q2：从理论上来说，Mono堆内存是越小越好（UWA是建议控制在40MB以内），分配频率越低越好。那单次比较大的内存分配和频率很高的（比如每帧）小内存分配，在性能影响上谁更大呢？单次GC的耗时，是受总体堆大小影响较大，还是受堆内引用对象数量的影响较大？简单来说，是要优先优化那些每帧分配的小内存还是单次较大的内存分配？GC对机器发热的影响大吗？ 优先优化那些每帧都分配的小内存。这个对于GC到来的影响比较大。频繁GC对于运行流畅性的影响比较大，从整体上来说，GC对于能耗的影响不大，比常规开销(渲染模块、UI模块等)要小很多。 单次较高的堆内存分配，建议要注意2MB以上的分配，查看其分配是否合理，尽可能避免8MB以上的分配。它主要的麻烦点在于撑大Mono堆内存峰值，一旦上去了就下不来。 该回答由UWA提供 Mono堆内存峰值高，最大的影响是会撑大Mono内存的占用量，而Mono向系统申请的内存是只增不减的。直白说就是游戏内存占用上升，风险是低内存设备上更容易闪退。 感谢Walker@UWA问答社区提供了回答 GC耗时肯定会受到影响。目前来讲，无论是IL2CPP还是Mono，GC都不分代，这也就意味着，回收的时候会遍历所有的节点。 感谢凯奥斯@UWA问答社区提供了回答 欢迎大家转至社区进一步交流： https://answer.uwa4d.com/question/5b5bd3471e88b37d34e6517d 资源管理 Q3：大家是怎么做代码分离的？游戏项目由于有多个部门需要共同访问，为了保护源代码，希望做到非技术部门在游戏工程只拿到加密后的DLL文件。 最初的想法是，各个部门都是拿同一个游戏工程，其中技术部直接获取源码，其他部门拿到DLL文件，技术编写完成后生成DLL给其他部门更新。但发现Unity中挂脚本组件是通过GUID+FileID的方式去匹配的，所以拿源码的同事是不同的脚本就有不同的GUID，拿DLL的同事则都是同一个GUID。导致不同部门之间没法在同一个工程上制作。 现在的做法是另外创建一个编译工程去生成各个平台对应的DLL文件，但是这样又比较繁琐。 PS：即使在已经做了模块分隔的情况下，导入DLL的时间比更新少量cs文件的时间多出很多，请问大家有没有更好的做法呢？ 这个我们是看部门需求的。 1）美术部门时常需…