美文网首页
Unity物理最佳实践(转载)

Unity物理最佳实践(转载)

作者: 86a262e62b0b | 来源:发表于2019-10-22 21:00 被阅读0次

    一. 层次(Layer)和层次碰撞矩阵(Layer Collision Matrix)

    所有新建的GameObject默认处于 Default 层,该层中的所有物体都可以相互碰撞,这样会比较消耗性能。
    应该为不同类型的GameObject设置不同的层,来设定哪些GameObject之间可以发生碰撞。
    新添加的层默认设置为可与所以已存在的层发生碰撞,要在碰撞矩阵中去掉不必要的碰撞关系,以减少碰撞监听和碰撞事件。

    碰撞矩阵界面位于 Edit-Project Settings-Physics : Layer Collision Matrix

    射线(Raycasts)

    射线比较消耗性能,其性能开销与射线的长度和场景中的碰撞器(Collider)的类型关系密切。
    下面列出一些优化射线性能的提示:

    • 尽量减少射线的数量。

    • 射线的长度够用即可。射线越长,引擎要检测的对象就越多。

    • 不要在 FixedUpdate() 中使用射线,也尽量不要在 Update() 中使用射线。

    • 注意射线所检测的碰撞器的类型,MeshCollider 的射线处理性能开销非常大。

      • 对于具有复杂网格的物体,一个比较好的解决方案是为其创建多个带有基础碰撞器的子对象,然后调整子对象碰撞器的形状到与父物体相近。
      • 若确实需要使用MeshCollider,尽量将其设置为 convex
    • 明确射线需要与哪些层发生碰撞,尽量在射线方法中使用层次遮罩。

      • 射线方法中的 layerMask 参数用于设置层次遮罩,它是位掩码而不是层id。
      • 要设置射线只与第10层(层id为10)的物体发生碰撞,layerMask参数应该为 1<<10
      • 要设置射线不与第10层的物体发生碰撞,layerMask参数应该为 ~(1<<10),不能省略括号。
      • 可以通过 LayerMask.NameToLayer("LayerName") 方法获取层的id。
      • 示例1: Physics.Raycast(ray, out hit, 1 << 10)
      • 示例2: Physics.Raycast(ray, out hit, ~(1 << 10))

    刚体(Rigidbody)

    刚体是在对象间进行物理交互所必须的组件,即使是只将碰撞器作为触发器(Tigger),也应该为对象添加刚体组件,这样可以确保 OnTrigger 事件正常工作。
    当多个对象具有层级关系且子对象具有碰撞器时,只需在最外层的父对象上添加一个刚体即可,无需为每个子对象添加刚体。
    不带有刚体的碰撞器对象会被引擎认为是 静态碰撞器(Static Collider)。要避免移动静态碰撞器对象,这一操作开销很大,因为这会导致引擎重新计算整个场景的物理数据。
    Profile 窗口的 CPU Profile 栏会在移动静态碰撞器时输出警告(warning)。

    这里我在Unity 5.6.3和Unity 2018.1.0中做了下测试,感觉反而是加了刚体之后每帧耗时增加了,Profile中也没看到警告,不知道是Unity内部做了升级还是我哪里没设置好,如果有人懂这里的改动,希望能给讲解一下!

    Fixed时间步长(Fixed Timestep)

    在时间管理器(Time Manager)中调整 Fixed Timestep 会直接影响到 FixedUpdate()物理计算 的更新频率,通过更改该值来在物理计算精度和CPU消耗中寻求平衡。时间管理器界面位于 Edit-Project Settings-Time : Time Manager

    相关文章

      网友评论

          本文标题:Unity物理最佳实践(转载)

          本文链接:https://www.haomeiwen.com/subject/lzycvctx.html