Unity 性能优化三:动画模块、物理模块

目录

动画模块

[Mecanim 模块](#Mecanim 模块)

[1.1 Animator active的数量](#1.1 Animator active的数量)

[1.1.1 Culling Mode](#1.1.1 Culling Mode)

[1.1.2 Optimize Gameobject](#1.1.2 Optimize Gameobject)

[1.1.3 Apply Root Motion](#1.1.3 Apply Root Motion)

[1.1.4 Compute Skinning](#1.1.4 Compute Skinning)

[1.1.5 Animator Initialize](#1.1.5 Animator Initialize)

[1.2 Legacy动画](#1.2 Legacy动画)

物理模块

[2.1 物理更新次数](#2.1 物理更新次数)

[2.1 减少不必要的Collision](#2.1 减少不必要的Collision)

[2.5 Auto Simulation](#2.5 Auto Simulation)

[2.6 RaycastCommand](#2.6 RaycastCommand)

[2.7 碰撞产生GC](#2.7 碰撞产生GC)

[2.8 Raycast、BoxCast、OverlapBox等函数产生的GC](#2.8 Raycast、BoxCast、OverlapBox等函数产生的GC)


动画模块

Mecanim 模块

1.1 Animator active的数量

1.1.1 Culling Mode
  1. 设置animator的culling model,主要是针对视野中看不到的动画体,animator 更新的内容主要有:Retarget、IK、回传的transform信息

Always animate: 看不见也都更新,UI要使用

Culling Update Transform:不更新上面的部分,但逻辑,根节点还是更新的,依然可以收到 OnAnimatorMove 回调,即位置保持更新,动画不再,其他动画将被跳过,比如骨骼动画,IK,OnAnimatorIK,一般推荐使用这个,但是有的复杂动画,在进入视野时会有问题,如果有问题,更改为Always animate

Culling Completely:看不见完全不更新,比如静态的花草动画,不更新也没关系

它主要影响playerloop里面的 Animator.Update()方法的耗时

1.1.2 Optimize Gameobject

在模型导入的RIG 栏中,勾选该选项,native层的骨骼数据,将不会回传到c#层,默认开启

它主要影响playerloop里面的 MeshSkinning.Update(),勾选后,将在主线程计算Animator.WriteJob

1.1.3 Apply Root Motion

对不需要使用根节点的动画,不勾选这个,它的耗时主要体现在Animator.ApplyBuiltinRootMotion函数,当该函数的耗时占比较高时,需要确认场景中Animator对象是否都需要产生位移。

1.1.4 Compute Skinning

在projectsetting 里面,可以勾选这个,表示是否是有GPU加速计算骨骼动画

经uwa测试,开启之后耗时比不开始还大,主要是主线程在等待GPU计算

1.1.5 Animator Initialize

每次setactive或Instantiate激活一个带有animator的组件,会调用这个方法,可以把该物体的animator组件关闭,然后把物体移出屏幕外

1.2 Legacy动画

Animation.Sample的调用次数显示了场景中实际在更新的Animation对象的数量,而它的父节点Animation.Update的调用次数则是显示了场景中存在的Animation对象的数量。因此,优化Legacy Animation动画耗时则是要减少Animation.Sample的调用次数。

物理模块

2.1 物理更新次数

  1. Unity物理系统的性能瓶颈主要体现在CPU端的耗时,它的主要耗时函数为FixedUpdate.PhysicsFixedUpdate。在开启Physics设置时,它的主要耗时堆栈是Physics.Processing和Physics.Simulate,需要针对这两个函数进行优化。

影响原因:

调用次数越多则耗时也就越高,调用次数受到Projectsetting->Time->Maximum Allowed Timestep和Fixed TimeStep的影响

Maximum Allowed TimeStep决定fxf了单帧物理最大调用次数,该值越小,单帧物理最大调用次数越少,一般为8~10FPS;Fixed TimeStep决定了FixedUpdate的更新间隔,该值越大,每帧物理更新调用次数越少。

当游戏卡顿时,单帧耗时比较长,则在下一帧会调用多次物理模拟,去跟上当前的时间进度

2.1 减少不必要的Collision

  1. Physics Layer中取消不必要的层之间的碰撞检测,避免多余的Contacts的产生。

  2. 尽量不要使用MeshCollider,如果非要用,可以勾选在Projectsetting->Prebake Collision Meshes

  3. collider 只控制碰撞结果,不进行物理模拟

  4. 如果不使用碰撞模拟,只想要触发结果,可以用trigger替代,也可以使用Collider.Bounds实现替代Trigger,避免使用Unity的物理模块。Trigger触发是比较方便的能够使用非物理模拟的方式来进行替换的一种Collision,使用C#逻辑来替代掉Trigger可以降低部分物理模块的耗时。

  5. 如果使用了rigidbody,尽量不要直接修改transform改变物体位置,这样会在物理系统里面重新计算其位置,使用add force、move position

2.5 Auto Simulation

  1. 如果项目不使用物理模拟,则在Edit>Project Settings>Physics关闭Auto Simulation选项,也可以通过脚本设置

  2. Auto Sync Transforms,在Edit>Project Settings>Physics中开启或关闭,默认关闭,它表示是否在transform 发生改变时,同步到物理系统,关闭时,会把transform的变化缓存到数组里面,在fixedupdate的时候更新,也可以通过脚本设置

需要注意的是,关闭Auto Simulation的情况下,如果需要使用射线检测,则需要开AutoSyncTransform选项

2.6 RaycastCommand

如果射线比较多,可以使用RaycastCommand代替Raycas,在子线程中执行射线检测

2.7 碰撞产生GC

OnCollisionEnter/Stay/Exit 会将返回的的结果,生成新的实例,分配到内存中,所以会造成GC,可以在projectsetting->physics->勾选Reuse Collision Callbacks,默认开启,这样就不会生成新的实例,而是重复使用一个

2.8 Raycast、BoxCast、OverlapBox等函数产生的GC

这些函数,返回的结果都是一个单独的实例,分配到内存中,造成GC开销,使用其对应的NonAlloc版函数

相关推荐
冰凌糕9 小时前
Unity3D 单例模式
unity
Artistation Game2 天前
九、怪物行为逻辑
游戏·unity·游戏引擎
百里香酚兰2 天前
【AI学习笔记】基于Unity+DeepSeek开发的一些BUG记录&解决方案
人工智能·学习·unity·大模型·deepseek
妙为2 天前
unreal engine5制作动作类游戏时,我们使用刀剑等武器攻击怪物或敌方单位时,发现攻击特效、伤害等没有触发
游戏·游戏引擎·虚幻·碰撞预设
dangoxiba2 天前
[Unity Demo]从零开始制作空洞骑士Hollow Knight第十三集:制作小骑士的接触地刺复活机制以及完善地图的可交互对象
游戏·unity·visualstudio·c#·游戏引擎
先生沉默先3 天前
使用Materialize制作unity的贴图,Materialize的简单教程,Materialize学习日志
学习·unity·贴图
十画_8243 天前
Visual Studio 小技巧记录
unity·visual studio
red_redemption3 天前
cpp,git,unity学习
git·unity·游戏引擎
tealcwu3 天前
【Unity踩坑】Unity更新Google Play结算库
unity·游戏引擎
先生沉默先3 天前
unity 默认渲染管线材质球的材质通道,材质球的材质通道
unity·游戏引擎·材质