如何更深入地掌握研发项目的物理性能?

如何更深入地掌握研发项目的物理性能?

这是第104篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间15分钟,认真读完必有收获。文末,我们的互动话题是,Mono和IL2CPP,哪个更受你的青睐,我们期待你的灼见!

UWA 问答社区:answer.uwa4d.com
UWA QQ群:465082844(仅限技术交流)

封面图片来自Google

物理

Q1:如何提高Unity物理引擎Physx的性能?我在场景中加入100个具有物理刚体的小人,并充分碰撞,发现低端机的帧率只能跑到10帧以下。

请输入图片描述

UWA:如果需要充分进行物理计算,这些拥挤在一起的小人很可能会造成大量的物理碰撞,进而造成很高的物理耗时。

在优化之前,题主需要先了解一些基础物理数值推荐,并不是所有设备都能流畅跑起100个自由制作的蒙皮模型的。所以,建议先看这篇文章:https://blog.uwa4d.com/archives/Simple_PA_Physics.html

另外,题主还需要看一下真机上的具体耗时瓶颈是否真正耗时在物理上,100个角色,如果Mesh量很大,渲染耗时也是不可忽视的,所以建议通过Unity Profiler来先确定一下真机上性能瓶颈。

最后,是否每个小人都需要精确的物理计算,是否可以通过一些射线求交、范围判断等性价比高的判断方法来代替纯物理碰撞?这需要题主从设计的角度上来进行权衡。

你并没有什么办法直接调用PhysX的API,所以所谓优化物理引擎的性能,倒不如说优化相关组件的性能。首先优先使用CharacterController而非RigidBody。然后尽量避免使用MeshCollider,用BoxCollider、SphereCollider和CapsuleCollider代替,如果不可避免,那么钩上Convex。当然,最好的优化就是不要用物理碰撞。射线能解决很多问题,但是射线也不是免费的,它的消耗跟场景里的面数正相关,当然设置射线的maxDistance和LayerMask能节省掉不必要的消耗。最好就是用简单的物理模型来描述问题,自己写代码实现。

感谢凯奥斯提供了回答

欢迎大家转至社区进行进一步交流:
https://answer.uwa4d.com/question/5ab47292d35eb22c10a0a403


编辑器

Q2:有什么方法可以禁止Unity自动编译脚本呢?

UWA:可以把Preferences > General > Auto Refresh的勾去掉,不过如果这样,如果资源在外部被修改,也不会自动重新导入了,会有些影响。

另外,也可以试试这两个函数EditorApplication.LockReloadAssemblies/ UnlockReloadAssemblies,参考文档:https://docs.unity3d.com/ScriptReference/EditorApplication.LockReloadAssemblies.html

该问题由UWA提供,欢迎大家转至社区进行进一步交流:
https://answer.uwa4d.com/question/5ab8a76dd35eb22c10a0a41f


渲染

Q3:我使用Texture2DArray的时候发现没有Mipmap效果,想问下怎么让Mipmap生效?原始的纹理都是开启Mipmap的。

UWA:在创建Texture2DArray时需要注意倒数第二个参数,设为true就表示开启Mipmap,参考文档:
https://docs.unity3d.com/ScriptReference/Texture2DArray-ctor.html

该回答由UWA提供,欢迎大家转至社区进行进一步交流:
https://answer.uwa4d.com/question/5ab7afd60b827e2c0bfdd18f


制作

Q4:现在有一张外部生成的Texture可以作为mainTex渲染,但希望获取它的内容保存下来,但是GetPixels是Texture2D的函数,所以想问问这样的Texture的内容该如何获取?

UWA:可以先通过Graphics.Blit把内容画到Render Texture里面,然后通过ReadPixels从RenderTexture生成一张Texture2D,假设sourceTex是原始的Texture,tex2D是最终生成的Texture2D,则代码如下:

RenderTexture renderTexture = new RenderTexture(sourceTex.width, sourceTex.height, 32);
Graphics.Blit(sourceTex, renderTexture);
Texture2D tex2D = new Texture2D(sourceTex.width, sourceTex.height, TextureFormat.RGBA32, false);
RenderTexture oldRT = RenderTexture.active;
RenderTexture.active = renderTexture;
tex2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
tex2D.Apply();
RenderTexture.active = oldRT;

该回答由UWA提供,欢迎大家转至社区进行进一步交流:
https://answer.uwa4d.com/question/5ab8a73c0b827e2c0bfdd196


Shader

Q5:我正在尝试自定义Terrain的Shader,发现内置Shader的末尾有这样两行,想问问其中的“Dependency”是做什么用的,后面指定的Shader起什么作用?
Dependency “AddPassShader” = “Hidden/TerrainEngine/Splatmap/Diffuse-AddPass”
Dependency “BaseMapShader” = “Diffuse”

UWA:Unity的文档中应该是没有描述过这个的作用, 不过在这篇博客里分析的比较清楚,https://alastaira.wordpress.com/2013/12/07/custom-unity-terrain-material-shaders

这是当Terrain使用的纹理超过4张时,Unity会用其中的AddPassShader来进行第二次渲染,并且blend上去。而BaseMapShader是用在低端显卡上的,只用一张纹理来显示的Shader。

该回答由UWA提供,欢迎大家转至社区进行进一步交流:
https://answer.uwa4d.com/question/5ab8b537d35eb22c10a0a426


互动话题

近年来,随着Unity官方对IL2CPP的大力支持和改进,越来越多的开发者在立项初期在Mono和IL2CPP之间犹豫徘徊。到底是Unity ILCPP编译好还是Mono的编译更好?IL2CPP的性能是否真有显著的变化?用过的朋友不妨来交流下你的心得!