​https://zhuanlan.zhihu.com/p/387410992?utm_medium=social&utm_oi=703841245952212992​

项目是否确实需要物理模块

unity3d:物理优化_Unity3d

降低固定时间步(Fixed Timestep)

Edit>>Project Settings >> Time,在那里,你能找到 Fixed Time Step ,它的默认值为 0.02

默认值为 0.02(每秒),如果更新不是很频繁不用太精确,可以 0.03 - 0.04

设置0.03后,FixedUpdate函数调用间隔

unity3d:物理优化_ide_02

Maximum Allowed TimeStep

这里我们需要先知道物理系统本身的特性,即当游戏上一帧卡顿时,Unity会在当前帧非常靠前的阶段连续调用N次FixedUpdate.PhysicsFixedUpdate,Maximum Allowed Timestep的意义就在于限制物理更新的次数。

Maximum Allowed TimeStep决定了单帧物理最大调用次数,该值越小,单帧物理最大调用次数越少。在Fixed Timestep为20ms的前提下,将Maximum Allowed Timestep从333ms下调为100ms,那么无论卡顿情况如何,该帧最多只会调用5次,而不是最多17次。

unity3d:物理优化_默认值_03

从monobehaviour的生命周期来看,FixedUpdate.在1次Updates(不是指Update api)可能会执行N次。
N≈Time.deltaTime/Time.fixedDeltaTime。
Time.fixedDeltaTime是固定不变的,N与Time.deltaTime成正相关。

假如上一帧(Update)的耗时变大(即Time.deltaTime变大)会导致下一帧FixedUpdate,物理计算的执行次数N变大,

又会导致CPU的性能消耗变大,从而又会影响当前帧(Update)的耗时,然后出现了“最坏”的情况。可能需要相当长的时间

才能缓解过来。所以Maximum Allowed Timestep限制Time.deltaTime的最大值,N的最大值也固定了,防止出现“最坏”的情况。

降低场景中rigibody数量

网格碰撞器比原始碰撞器具有更高的性能开销,所以尽量少用。通常是在子网格上使用原始碰撞器来模拟一个网格的近似形状。子网格的碰撞器将被母网格的刚体部分集合成为一个复合的碰撞器。虽然轮碰撞器不是严格意义上的实体对象碰撞器,但是它们仍然有着很高的CPU开销。物理计算总量取决于非休眠刚体数目、场景中碰撞器的数目和碰撞器的复杂性。您可以使用内部Profiler来检测场景中一共使用了多少物理对象。

如果是OnCollisionEnter要两个物体都要刚体

如果OnTriggerEnter只需要一个物体要刚体

unity3d:物理优化_默认值_04

去掉不用的碰撞检测

不需要盾牌与地面的碰撞。(a,b之间碰撞不要,包括aa,ab,bb)

unity3d:物理优化_Unity3d_05

或者代码控制
Physics.IgnoreLayerCollision(LayerMask.NameToLayer(“A”), LayerMask.NameToLayer(“B”), true);

尽量不用网格碰撞

即使用了网格碰撞,可以用凸面

unity3d:物理优化_物理优化_06

减少Raycast使用

但部分项目确实需要较多的Raycast,例如弹幕游戏中Raycast数量往往较多,这种情况下可以通过Job System下的RaycastCommand将Raycast的耗时从主线程转移到子线程上,进而减少其耗时。

Auto Sync Transforms

勾选Auto Sync Transforms后,发生Physics Query时,Unity会将Rigidbody/Collider的Tranform变化同步到物理引擎,如Position,Scale等。另外勾选AutoSimulation时,Unity会在每次物理更新的时候自动同步一次Rigidbody和Collider,所以当关闭AutoSimulation后,如果项目中使用了射线检测或者NGUI,通常需要Auto Sync Transforms进行勾选,否则会发生射线检测结果不准确或者UI事件不响应的情况。
同步操作在一般情况下的性能开销很低,通常只在超大场景,且有大量物体均加载到场景中,才会出现较高的耗时问题。