UPL7-4——物理系统基础设置

物理系统基础设置

我们可以在 Project Settings 中对物理系统进行一些基础设置,
这些设置看起来只是和物理系统相关,但是实际上其中有很多的参数都会实实在在的影响我们的性能,
因此,了解这些基础设置,对于我们优化性能也有一定的帮助!

解算器

解算器(Solver)在 Unity 物理系统里其实是指物理系统里负责解方程的模块,就是 Unity 物理中用来处理碰撞,关节约束的方程求解器
它决定物体在发生接触后该怎么调整位置和速度,迭代次数越多越稳定,代价是 CPU 的消耗也更高(迭代指的就是解算器的计算次数)

在物理模拟中,碰撞检测只是发现 物体 A 和物体 B 重叠或接触,检测到重叠或者接触后,接下来要处理两个问题:

  1. 它们要分开多少
  2. 它们的速度,角速度要怎么调整?

这就涉及到一系列约束条件:

  1. 碰撞不允许重叠,需要位置约束
  2. 摩擦,弹性系数要生效,需要速度约束
  3. 关节要维持结构,需要关节约束

这些约束本质上会形成一组线性方程和不等式,解算器就是负责解这些方程,求出新的位置与速度

举例:解算器在 Unity 内的作用

输入信息:

  1. 碰撞检测生成的接触点
  2. 所有关节约束
  3. Rigidbody 的质量,惯性,速度,力

等等

过程:按一定的算法迭代求解(近似解,不是数学上的精确解),每迭代一次,位置和速度就更接近符合物理规律的状态

输出:更新后的 Rigidbody 的位置,选择,速度,角速度

3D 物理系统设置

Shared(共享)页签

image

  • Gravity 重力

    使用 x、y 和 z 轴来设置应用于所有刚体组件的重力大小。
    对于现实的重力设置,请对 y 轴应用负数。重力以每秒平方世界单位定义。

    注意:如果您增加重力,您可能还需要增加 Default Solver Iterations(默认解算器迭代次数) 值以保持稳定的接触。

  • Layer Collision Matrix 碰撞层矩阵

    定义 基于层的碰撞 检测系统如何运行。要选择碰撞矩阵上哪些层与其他层交互,请选中它们各自的复选框。

    关于碰撞层矩阵,详见:UPL7-3——碰撞层矩阵

Game Object 页签

image

  • 基础参数

    • Default Material(默认物理材质)

      设置默认的物理材质,如果 Collider 没有指定材质,就会用这个。
      物理材质决定摩擦系数、弹性等

    • Bounce Threshold(反弹阈值)

      小于这个相对速度的碰撞不会触发弹性反弹(会被当作静止接触处理),避免低速抖动

    • Default Max Depenetration Velocity(默认最大脱离速度)

      当物体重叠时,物理引擎会把它们推出去。这个值限制推出的最大速度,防止过快弹飞。

    • Sleep Threshold(休眠阈值)

      刚体速度(线性 + 角速度)低于这个阈值时,进入“休眠”以减少计算

    • Default Contact Offset(默认接触偏移量)

      碰撞体周围的额外“皮肤”厚度。 值越大,越早检测到接触(避免高速漏检),但过大会导致不必要的碰撞。

  • 解算器相关

    • Default Solver Iterations(默认解算器迭代次数)

      每次物理步长里,解算器迭代的次数(影响位置/旋转的精度和稳定性) 越高越稳定但更耗 CPU

    • Default Solver Velocity Iterations(默认解算器速度迭代次数)

      专门用于解算速度的迭代次数,主要影响摩擦、反弹的稳定性

  • 碰撞检测配置

    • Queries Hit Backfaces(是否查询射线命中背面)

      射线 Raycast​ 是否检测 MeshCollider 的背面,关掉通常更高效

    • Queries Hit Triggers(是否查询射线命中触发器)

      射线 Raycast​ 是否检测触发器(isTrigger​ 的 Collider

    • Enable Adaptive Force(是否启用自适应力稳定堆叠物体):通常保持关闭

      动态调节接触力来稳定堆叠物体,通常保持关闭

  • 模拟模式,同步转换,碰撞回调相关

    • Simulation Mode(模拟模式)

      image

      Unity 物理引擎每一帧都需要推进物理世界一次
      (即调用 Physics.Simulate(deltaTime)
      Simulation Mode 就是控制这个物理步进由谁来执行

      • Fixed Update: 物理模拟会在 Unity 的 FixedUpdate 循环中自动执行

        通过 Time > Fixed Timestep 控制
        独立于渲染帧率,即使渲染卡顿,物理也会按固定步长“补模拟”

        • 优点:稳定、一致,最适合大多数游戏。
        • 缺点:可能在掉帧时出现 多次物理步进 ,造成 CPU 峰值。
      • Update: 物理模拟直接在每帧的 Update 里执行(不常用)

        跟随渲染帧率 → 60FPS 就模拟 60 次,30FPS 就模拟 30 次

        • 优点:更流畅(物理和画面完全同步),适合对物理依赖很轻的项目(比如休闲游戏)。
        • 缺点:帧率不稳定时,物理表现也会抖动,可能在主机、移动端不理想,
      • Script:在代码里手动调用 Physics.Simulate(deltaTime),自己更新

        你完全控制物理何时更新(甚至可以一帧模拟多次,或隔几帧才模拟一次
        一般用于特殊需求,比如:

        1. 自己写物理
        2. 多场景物理不同步
        3. 回放系统,需要按精确的时间轴重现物理

        优缺点:

        • 优点:可控性强
        • 缺点:管理复杂度高,容易出错
    • Auto Sync Transforms(是否自动同步转换)

      如果打开,每次修改 Transform​ 都会自动同步到物理引擎。
      性能代价很高,推荐关闭,用 Rigidbody.MovePosition​ 或 MoveRotation 控制移动

    • Reuse Collision Callbacks(是否复用碰撞回调)

      是否复用 Collision 对象,减少 GC 时推荐开启

    • Invoke Collision Callbacks(是否调用碰撞回调函数)

      是否触发碰撞回调(OnCollisionEnter/Stay/Exit
      如果关掉,回调不会触发(但物理仍然计算)

  • 接触对和广义检测

    • Contact Pairs Mode(接触对配对模式)

      控制物理接触对的生成模式

      当两个 Collider 的 AABB 在 Broadphase 阶段重叠时,PhysX 会把它们作为一个候选对送到 Narrowphase 精检测,如果 Narrowphase 确认它们真的发生接触,就会生成一个 Contact Pair,其中包含:

      1. 哪两个 Collider 接触了
      2. 接触点的位置、法线、穿透深度
      3. 是否是触发器对
      4. 是否涉及连续碰撞检测

      这些 Contact Pair 决定 碰撞解算 和 物理碰撞回调事件 (OnCollisionXXX​ / OnTriggerXXX) 的触发

      image

      • Default Contact Pairs(默认接触对)

        只生成必要的接触对

      • Enable Kinematic Kinematic Pairs(启用运动学接触对)

        默认情况,Kinematic vs Kinematic 不会生成接触对,因为它们都不受力,不需要解算
        打开后,Kinematic vs Kinematic 之间也会生成 Contact Pair
        你想检测 两个运动学物体的触发事件,可以开启
        但是会增加 Broadphase / Narrowphase 处理的对数,性能消耗上升

      • Enable Kinematic Static Pairs(启用运动学静态接触对)

        默认情况,Kinematic vs Static 不会生成接触对
        打开后,Kinematic vs Static 之间会生成 Contact Pair
        需要知道运动学物体(如移动平台)是否“接触到”静态场景几何,可以开启
        但是同样会增加 Pair 数量,性能开销更大

      • Enable All Contact Pairs(生成所有可能的接触对)

        包含触发器、连续碰撞检测、运动学刚体等等
        通常只在调试、诊断问题时用,性能消耗最高

    • Broadphase Type(广义检测类型)

      决定广义检测的算法

      image

      • Sweep And Prune(SAP):默认,基于轴排序,高效。
      • Automatic Box Pruning(自动框裁剪):适合超大场景,Unity 内部实验功能
  • 摩擦和精度

    • Friction Type(摩擦类型)

      碰撞摩擦的计算方式

      image

      • Patch Friction Type(补块摩擦类型):在接触点块里球平均值
      • One Directional / Two Directional Friction(单向/双向摩擦):更精确或更快的选项,影响摩擦模拟。消耗更大
    • Enable Enhanced Determinism(启用增强确定性)

      打开后,物理计算会更加确定性(不同平台 / 运行一致),但有性能开销

    • Improved Patch Friction(是否启用改进后的补块摩擦计算)

      优化摩擦模型的开关,可以提高堆叠稳定性,有性能开销

  • 解算器类型

    • Solver Type(解算器类型)

      image

      • Projected Gauss Seidel(PGS) PhysX 默认解算器,效率高但数值不完全稳定
      • Temporal Gauss Seidel(TGS): Unity 2019+ 引入,更稳定,尤其是关节/堆叠场景,但更耗性能。
  • 速度、缓存、阈值

    • Default Max Angular Speed(默认最大角速度)

      刚体的最大角速度,防止旋转过快导致数值不稳定

    • Scratch Buffer Chunk Count(临时缓冲区块计数)

      物理世界一次模拟可用的临时内存块数,通常不用改,除非调优大规模物理场景(上万刚体、成千接触点,才需要调高)

      如果临时缓冲区太小,物理世界复杂时(很多碰撞体/接触点),PhysX 会频繁向系统申请额外内存(malloc),造成性能抖动和 GC 压力
      如果设得太大,会占用多余内存,但换来更稳定的性能

      • 小/中型项目(常见移动游戏、独立游戏):保持默认,不用动
      • 大型项目(物理沙盒游戏、MMO 有几千刚体):可以适当调高

      方法:用 Profiler​ 看物理模块里的内存分配峰值,如果频繁分配,就增大

    • Fast Motion Threshold(快速运动阈值)

      如果物体的运动超过这个阈值,会强制使用连续碰撞检测(防止漏检)。
      默认值是个极大数(相当于关闭了该功能)

Cloth(布料)页签

此页签的设置仅使用于布料物理

image

  • Gravity Override:布料重力重载

    设置每个轴上布料组件的重力值。
    默认情况下,X 设置为 0,Y 设置为 -9.81,Z 设置为 0。

  • Enable Inter-Collision:是否启用布料粒子相互碰撞

    启用后显示下方两个属性,该值默认不启用

    • Inter-Collision Distance

      定义每个相互碰撞的布料粒子周围球体的直径(以世界单位为单位)。
      Unity 确保这些球体在模拟过程中不会重叠。距离应小于配置中两个粒子之间的最小距离。如果距离更大,布料碰撞可能会违反距离约束,导致抖动。

    • Inter-Collision Stiffness

      定义当相互碰撞的布料粒子比距离值更近时,它们之间的分离力的强度。
      该值是 PhysX 乘以分离力的系数;布料求解器随后根据您提供的该值计算刚度。

2D 物理系统设置

image

  • 常规设置

    • Gravity(重力的方向与大小)

      设置 2D 世界中的重力方向和大小,默认为朝下的重力

    • Default Material(默认物理材质)

      默认的 2D 物理材质(Physics Material 2D),
      Collider2D 没有指定材质时使用

  • 解算相关

    • Velocity Iterations(速度迭代次数)

      数值越高,物体碰撞时速度的计算越精确,但性能消耗也更大

    • Position Iterations(位置迭代次数)

      影响物体在碰撞中的位置校正精度。

    • Bounce Threshold(反弹阈值)

      低于此速度的碰撞不会产生弹性反弹,避免小抖动

    • 修正相关属性

      • Max Linear Correction(最大线性位置修正)

        用于防止物体因浮点误差穿透时的修正量

      • Max Angular Correction(最大角度修正)

        与上面类似,但针对旋转

      在物理模拟里,由于浮点误差大时间步长高速运动,物体可能会发生轻微的 重叠

      Box2D 的解算器会通过 位置校正 来把物体推开,避免它们无限重叠,但是如果“推开量”没有限制:

      1. 可能一次性把物体推出很远,导致抖动或跳跃
      2. 特别是高速物体/薄物体,可能瞬移到奇怪的位置

      因此 Box2D 给出两个安全阈值:
      限制一次迭代中,线性位置和旋转 修正的最大距离

      举例说明:

      假设两个刚体发生了 0.5 米的重叠:Max Linear Correction = 0.2(默认)
      引擎只允许这次迭代最多修正 0.2 米,可能需要多次迭代(每帧内多次解算)逐步把它们分开
      如果把这个值调大(比如 1),一次迭代可能就能修正 0.5 米的重叠,但可能导致物体瞬间弹开,不稳定

    • Max Translation Speed(最大线速度)

      防止物体因速度过大导致物理计算不稳定

    • Max Rotation Speed(最大角速度)

      同样是防止过大旋转速度带来的不稳定

  • 穿透修正相关

    • Baumgarte Scale(位置修正系数)

      决定在碰撞时,穿透误差的修正比例 表现为温柔的推开

    • Baumgarte Time Of Impact Scale(TOI 修正系数)

      主要用于高速物体的连续碰撞检测
      表现为粗暴推开,因为高速物体必须马上分开,否则会穿透

    • 举例:

      假设两个物体重叠了 0.1m:

      Baumgarte Scale = 0.2,每次迭代修正 0.1 * 0.2 = 0.02m,大约需要 5 次迭代才能完全分离
      Baumgarte TOI Scale = 0.75,每次迭代修正 0.1 * 0.75 = 0.075m,只要 2 次迭代就能分离,更快

      主要用于修正连续碰撞检测的物体

  • 休眠相关

    • Time To Sleep(进入休眠时间)

      进入休眠的延迟时间

    • Linear Sleep Tolerance(线性睡眠耐受力)

      线速度低于该值时,物体可进入休眠

    • Angular Sleep Tolerance(角速度耐受性)

      角速度低于该值时,物体可进入休眠

  • 射线、碰撞检测相关

    • Default Contact Offset(默认接触偏移量)

      用于避免浮点误差导致的穿透

    • Contact Threshold(接触阈值)

      主要用于 CCD(连续碰撞检测)

    • Queries Hit Triggers(是否查询触发器命中)

      射线检测是否检测触发器

    • Queries Start In Colliders(是否查询从碰撞器开始的命中)

      射线起点在 Collider 内时是否算命中

    • Callbacks On Disable(是否禁用回调)

      对象禁用时是否触发碰撞回调

    • Reuse Collision Callbacks(是否重用碰撞回调)

      是否重用碰撞回调对象(减少 GC)

      此选项在启用时可以提高性能。禁用时,由于垃圾收集(GC)压力,可能会导致性能不佳。因此,默认设置为启用。

  • 模拟模式

    • Auto Sync Transforms(是否自动同步转换)

      如果打开,每次修改 Transform​ 都会自动同步到物理引擎。
      性能代价很高,推荐关闭,用 Rigidbody.MovePosition​ 或 MoveRotation 控制移动

    • Simulation Mode(模拟模式)

      Unity 物理引擎每一帧都需要推进物理世界一次(即调用 Physics.Simulate) Simulation Mode 就是控制,这个物理步进由谁来执行

      image

      • Fixed Update: 物理模拟会在 Unity 的 FixedUpdate 循环中自动执行

        通过 Time > Fixed Timestep 控制
        独立于渲染帧率,即使渲染卡顿,物理也会按固定步长“补模拟”

        • 优点:稳定、一致,最适合大多数游戏。
        • 缺点:可能在掉帧时出现 多次物理步进 ,造成 CPU 峰值。
      • Update: 物理模拟直接在每帧的 Update 里执行(不常用)

        跟随渲染帧率 → 60FPS 就模拟 60 次,30FPS 就模拟 30 次

        • 优点:更流畅(物理和画面完全同步),适合对物理依赖很轻的项目(比如休闲游戏)。
        • 缺点:帧率不稳定时,物理表现也会抖动,可能在主机、移动端不理想,
      • Script:在代码里手动调用 Physics.Simulate(deltaTime),自己更新

        你完全控制物理何时更新(甚至可以一帧模拟多次,或隔几帧才模拟一次
        一般用于特殊需求,比如:

        1. 自己写物理
        2. 多场景物理不同步
        3. 回放系统,需要按精确的时间轴重现物理
        • 优点:可控性强
        • 缺点:管理复杂度高,容易出错
    • Simulation Layers(模拟层)

      哪些 Layer 参与物理模拟

  • 调试相关

    • Gizmos(小工具): 编辑器中如何绘制碰撞体

      image

      • Nothing:不显示任何 2D 物理相关的 Gizmos
      • Everything:显示所有可用的 Collider Gizmos(相当于全选)
      • All Colliders:显示场景中所有的 2D Collider
      • Colliders Outlined:显示碰撞体的轮廓线,常用来直观检查碰撞体形状
      • Colliders Filled:显示碰撞体的填充区域,一般用来区分重叠的碰撞体
      • Colliders Sleeping:高亮显示当前处于休眠状态(Sleeping)的刚体碰撞体对调试性能优化很有帮助,可以看到哪些物体已经停止物理计算
      • Collider Contacts:显示碰撞体之间的 接触点(小点/小线)
        用于调试碰撞检测,特别是需要确认两个物体是否真的在物理层面发生接触
      • Collider Bounds:显示碰撞体的 包围盒(AABB)
        方便观察 Unity 内部用于快速检测的边界区域
  • 多线程相关

    • Use Multithreading(使用多线程)

      启用 2D 物理的多线程 Job 系统。开启后,物理运算会分配到多个 CPU 核心

    • Use Consistency Sorting(启用一致性排序)

      保证任务执行顺序可预测(调试时更稳定)。
      关闭会更快,但可能出现非确定性结果

    • Job 分批参数(每个 Job 处理多少对象)

      决定各种物理计算任务(插值、接触生成、清理等)如何分批给 Job
      数值越大 = Job 数量少(减少调度开销,单 Job 任务重)
      数值越小 = Job 数量多(更分散,可利用更多线程,但调度开销大)

      • Interpolation Poses Per Job: 插值姿态计算时,每个 Job 处理的刚体数量
      • New Contacts Per Job: 每个 Job 处理新生成的接触点的数量
      • Collide Contacts Per Job: 碰撞检测中,每个 Job 处理的接触数
      • Clear Flags Per Job: 清理物体标记时,每个 Job 批处理的数量
      • Clear Body Forces Per Job: 清理刚体受力时,每个 Job 处理的刚体数
      • Sync Discrete Fixtures Per Job: 每个Job同步离散碰撞体(非连续检测)的数量
      • Sync Continuous Fixtures Per Job: 每个Job同步连续碰撞体(CCD)的数量
      • Find Nearest Contacts Per Job: 查找最近的接触点时,每个 Job 处理的数量
      • Update Trigger Contacts Per Job: 更新触发器接触点时,每个 Job 的数量
    • Island Solver(岛屿解算器)相关

      物理系统会把一组相互作用的刚体、关节、碰撞点组成一个 Island(岛屿),然后单独解算,下面这些参数决定 岛屿解算如何拆分到多线程执行,控制何时分 Job 解算

      关于岛屿相关内容,可见:UPL7-7——刚体相关

      • Island Solver Cost Threshold: 当岛屿的计算成本超过该阈值时,会拆分为多个 Job
      • Island Solver Body Cost Scale: 刚体的计算成本系数。值越大,刚体对总计算成本影响越大
      • Island Solver Contact Cost Scale: 接触点的计算成本系数
      • Island Solver Joint Cost Scale: 关节的计算成本系数
      • Island Solver Bodies Per Job: 解算岛屿时,每个 Job 处理的刚体数量
      • Island Solver Contacts Per Job: 解算岛屿时,每个 Job 处理的接触数量
    • 多线程属性调整建议:

      1. Unity 已经针对常见项目做过平衡,通常不需要调整这些参数
      2. 如果物体数量非常多、CPU 多核
        可以适当 降低 per job 数值 → 让更多 Job 并行
      3. 如果物体不多,但调度开销高
        可以适当 增大 per job 数值 → 减少 Job 数量