Unity DOTS物理引擎的核心分析与详解

最近DOTS发布了正式的版本,同时基于DOTS的理念实现了一套高性能的物理引擎,今天我们来给大家分享和介绍一下这个物理引擎的使用。

Unity.Physics的设计哲学

Unity.Physics是基于DOTS设计思想的一个高性能C#物理引擎的实现, 包含了物理刚体的迭代计算与碰撞检测等查询。Unity.Physics的设计理念与PhyX和Havok有所不同,它们追求的是全特性的物理模拟,而Unity.Physics追求的是最常用的一些物理机制的实现,相比传统的物理引擎,它实现的是物理引擎的核心子集,这样导致比传统的物理引擎实现起来更简单与高效,同时能满足大部分的需求。

对惹,这里有一 个游戏开发交流小组,大家可以点击进来一起交流一下开发经验呀!

传统的物理引擎在迭代计算的时候为了保证物理引擎计算结果的稳定性,缓存了很多的状态,这样就给整个系统设计增加了复杂度与开销。比如传统物理引擎还考虑到了网络游戏的情况下,你整个物理引擎的回滚与向前迭代计算。Unity.Physics就丢弃掉了这些,使得更容易控制和更高效。Unity.Physics物理引擎的迭代与计算都是基于Job与ECS机制的,由于没有cache计算中的物理状态,导致它的性能会比传统的物理引擎在某些方面性能要好。Unity.Physics的里面的物理参数与数据描述与传统的Havok物理引擎兼容,这样如果我们的项目中要追求物理引擎的全面性与稳定性,我们可以很容易的使用Havok等商业的物理引擎。在Unity DOTS里面,如果你获得了物理引擎Havok的授权,你可以直接在Unity DOTS中使用Havok物理引擎。

Unity.Physics的源码目录结构如下:

  • Base: 包含了Unity.Pysics物理引擎使用的基本数据容器与数学计算;
  • Collistion: 包含了所有的碰撞检测与空间检测的算法代码;
  • DFG:包含了DataFlowGraph数据,在碰撞世界里面执行碰撞与设想检测;
  • Dynamics:包含了所有的物理引擎的运动计算,约束计算,迭代计算;
  • ECS: 包含了将ECS的组件数据导入,导出到Unity.Physics引擎中;
  • Extensions: 包含了一些工具性质的代码,扩展的一些组件,调试工具等;

Unity.Physics的物理引擎的全局设置

要对Unity DOTS的物理引擎做全局设置,我们可以给DOTS里面的SubScene添加一个"PhysicsStep"的组件实例。如下图所示:

  • Simulation Type: 下拉选项包含Unity Physics, Havok Physics, None,你可以来选择物理引擎的内核,如果你获得了Havok的商业授权,你就可以看到Havok Physics的选项。
  • Gravity: 设置整个物理世界的张力加速度;
  • Solver Iteration Count: 设置每次迭代计算的次数,次数越大,计算结果越精确稳定,但是也消耗更多的性能;
  • Multi Threaded: 是否基于多线程来进行迭代物理计算,如果勾选上,物理引擎会使用较多的线程来进行迭代计算,否则就使用少量的线程来迭代计算。

Unity DOTS 物理引擎简单的案例

接下来利用Unity DOTS来实现一个简单的物理引擎的案例,编写一个脚本TargetAuthoring.cs, 代码如下:

复制代码
using Unity.Entities;
using UnityEngine;

public struct Target : IComponentData
{
    public Entity TargetEntity;
    public float MaxDistance;
}

public class TargetAuthoring : MonoBehaviour
{
    public GameObject TargetGameObject;
    public float MaxDistance;
}

public class TargetAuthoringBaker : Baker<TargetAuthoring>
{
    public override void Bake(TargetAuthoring authoring)
    {
        var component = new Target
        {
            MaxDistance = authoring.MaxDistance,
            TargetEntity = GetEntity(authoring.TargetGameObject)
        };
        AddComponent(component);
    }
}

再新建一个MovingBodyAuthoring.cs的文件,代码如下:

复制代码
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Transforms;
using UnityEngine;

public struct MovingBody : IComponentData
{
    public https://zhida.zhihu.com/search?q=float&zhida_source=entity&is_preview=1 Velocity;
}

public class MovingBodyAuthoring : MonoBehaviour
{
    public float Velocity;
}

class MovingBodyAuthoringBaker : Baker<MovingBodyAuthoring>
{
    public override void Bake(MovingBodyAuthoring authoring)
    {
        var component = new MovingBody
        {
            Velocity = authoring.Velocity
        };
        AddComponent(component);
    }
}

public partial struct MovingBodySystem : ISystem
{
    public void OnUpdate(ref SystemState state)
    {
        foreach (var(target, transform, moving, velocity) in SystemAPI.Query<RefRO<Target>, RefRO<LocalTransform>, RefRW<MovingBody>, RefRW<PhysicsVelocity>>().WithAll<MovingBody>())
        {
            var targetPosition = SystemAPI.GetComponent<LocalTransform>(target.ValueRO.TargetEntity).Position;
            var direction = math.normalize(targetPosition - transform.ValueRO.Position);

            if (math.distance(targetPosition, transform.ValueRO.Position) < target.ValueRO.MaxDistance)
                velocity.ValueRW.Linear = moving.ValueRO.Velocity * direction;
            else
                velocity.ValueRW.Linear = new float3(0, 0, 0);
        }
    }
}

打开SubScene场景,创作3个物体,一个地面(Cube),一个球体(Sphere),一个立方体节点(Target)。在球体上挂TargetAuthoring与MoveBodyAuthoring两个组件,并设置MoveBodyAuthoring的Velocity与MaxDistance为1与5,设置TargetAuthoring组件的的TargetGameObject为Target节点对象。

运行,效果如下:

相关推荐
在路上看风景12 小时前
## 2.2 状态同步
unity
霜绛13 小时前
Unity:lua热更新(一)——AB包AssetBundle、Lua语法
笔记·学习·游戏·unity·lua
霜绛13 小时前
Unity:lua热更新(二)——Lua语法(续)
笔记·学习·unity·游戏引擎·lua
yi碗汤园14 小时前
【一文了解】C#反射
开发语言·unity·c#
HahaGiver66615 小时前
Unity Shader Graph 3D 实例 - 基础的模型贴图渲染
3d·unity·游戏程序·贴图·游戏美术
HahaGiver66615 小时前
Unity Shader Graph 3D 实例 - 一个简单的3D打印效果
3d·unity·游戏引擎
AA陈超15 小时前
ASC学习笔记0004:通知相关方能力规格已被修改
c++·笔记·学习·游戏·ue5·游戏引擎·虚幻
胖胖求游戏19 小时前
Unity热更新——AB包和Lua
unity·游戏引擎·lua
为你写首诗ge20 小时前
【Unity知识分享】Unity中获取Pico设备的序列号(SN码)
unity
B0URNE1 天前
什么是虚拟现实(VR)?
unity·ue5·vr