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 float 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节点对象。

运行,效果如下:

今天的分享就到这里,需要本篇文章完整的项目工具与源码的同学可以+ 企.鹅.裙 428 540 563


下面是DOTS的VIP课程前18节视频,免费观看

Unity DOTS进阶与项目实战(B站18集)

第001课DOTS的环境安装与准备事项

第002课 DOTS的核心机制与概述

第003课DOTS的SubScene

第004课Component的概述与普通组件的Baker

第005课System与SystemGroup概述

第006课DOTS中的ECS核心概念总结

第007课Baking系列之Baking与Baker详解

第008课Baking系列之BakingSystem与BakingWorld详解

第009课FilterBakingOutput与PrefabsInBaking

第010课BlobAsset核心机制分析

第011课Aspect核心机制分析

第012课 StructChange核心机制详解

第013课Managed与Unmanaged Component详解与性能分析

第014课ShareComponent核心机制与性能分析

第015课CleanupComponent核心分析

第016课 Dynamic Buffer Component详解与分析

第017课Tag与Chunk Component详解与分析

第018课Enableable与Singleton组件详解与分析

相关推荐
Elastic 中国社区官方博客10 小时前
使用 LangGraph 和 Elasticsearch 构建强大的 RAG 工作流
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
虾球xz14 小时前
游戏引擎学习第246天:将 Worker 上下文移到主线程创建
c++·学习·游戏引擎
程序员爱钓鱼17 小时前
从零开始开发一个简易的五子棋游戏:使用 HTML、CSS 和 JavaScript 实现双人对战
前端·javascript·游戏开发
虾球xz17 小时前
游戏引擎学习第240天:将渲染器移至第三层
c++·学习·游戏引擎
林枫依依20 小时前
Unity Webgl在编辑器中报错:Cannot connect to destination host
unity·编辑器·webgl
KhalilRuan20 小时前
Unity-Shader详解-其一
unity·游戏引擎
Clank的游戏栈1 天前
Unity多线程渲染指令队列设计与集成技术详解
windows·unity·游戏引擎
Thomas_YXQ1 天前
Unity3D Lua集成技术指南
java·开发语言·驱动开发·junit·全文检索·lua·unity3d
胜天半子_王二_王半仙1 天前
godot源码编译
游戏引擎·godot
Thomas_YXQ1 天前
Unity3D IK解算器技术分析
开发语言·搜索引擎·unity·全文检索·unity3d·lucene