当前位置: 首页 > article >正文

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

运行,效果如下:

动图


http://www.kler.cn/a/315014.html

相关文章:

  • StructuredStreaming (一)
  • 浅谈:基于三维场景的视频融合方法
  • 大模型时代,呼叫中心部门如何自建一套大模型在线客服?
  • Python中异常处理小测验
  • 使用Docker快速部署FastAPI Web应用
  • MySQL系列之如何在Linux只安装客户端
  • 植物大战僵尸【源代码分享+核心思路讲解】
  • [每日一练]MySQL中的正则表达式的应用
  • Day 9:1306 跳跃游戏III
  • 神经网络构建原理(以MINIST为例)
  • Java | Leetcode Java题解之第416题分割等和子集
  • 国内可以使用的ChatGPT服务【9月持续更新】
  • 828华为云征文 | 云服务器Flexus X实例:多智能体对话框架 AutoGen 部署和实例运行
  • 重修设计模式-结构型-门面模式
  • python 实现binomial coefficient二项式系数算法
  • excel 单元格一直显示年月日
  • Contact Form 7最新5.9.8版错误修复方案
  • ClickHouse 与 Quickwit 集成实现高效查询
  • 适用于QF的存档系统
  • react的事件绑定
  • vulnhub(12):bob 1.0.1(gpg文件解密)
  • @PostConstruct
  • <刷题笔记> 力扣236题——二叉树的公共祖先
  • 全面详尽的 PHP 环境搭建教程
  • C++ 元编程
  • 18938 汉诺塔问题