https://zhuanlan.zhihu.com/p/387410992?utm_medium=social&utm_oi=703841245952212992
项目是否确实需要物理模块
降低固定时间步(Fixed Timestep)
Edit>>Project Settings >> Time,在那里,你能找到 Fixed Time Step ,它的默认值为 0.02
默认值为 0.02(每秒),如果更新不是很频繁不用太精确,可以 0.03 - 0.04
设置0.03后,FixedUpdate函数调用间隔
Maximum Allowed TimeStep
这里我们需要先知道物理系统本身的特性,即当游戏上一帧卡顿时,Unity会在当前帧非常靠前的阶段连续调用N次FixedUpdate.PhysicsFixedUpdate,Maximum Allowed Timestep的意义就在于限制物理更新的次数。
Maximum Allowed TimeStep决定了单帧物理最大调用次数,该值越小,单帧物理最大调用次数越少。在Fixed Timestep为20ms的前提下,将Maximum Allowed Timestep从333ms下调为100ms,那么无论卡顿情况如何,该帧最多只会调用5次,而不是最多17次。
从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只需要一个物体要刚体
去掉不用的碰撞检测
不需要盾牌与地面的碰撞。(a,b之间碰撞不要,包括aa,ab,bb)
或者代码控制
Physics.IgnoreLayerCollision(LayerMask.NameToLayer(“A”), LayerMask.NameToLayer(“B”), true);
尽量不用网格碰撞
即使用了网格碰撞,可以用凸面
减少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事件不响应的情况。
同步操作在一般情况下的性能开销很低,通常只在超大场景,且有大量物体均加载到场景中,才会出现较高的耗时问题。