DOTS Unity.Physics物理引擎碰撞事件处理

这篇具有很好参考价值的文章主要介绍了DOTS Unity.Physics物理引擎碰撞事件处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近DOTS发布了正式的版本,同时基于DOTS的理念实现了一套高性能的物理引擎,今天我们给大家分享和介绍一下这个物理引擎的碰撞事件处理以及核心相关概念。

Unity.Physics物理引擎的主要流程与Pipeline

 Unity.Physics物理引擎做仿真迭代计算的时候主要通过以下步骤来执行:

   step1: 从entity里面的ECS组件中获取我们当前的物体的状态数据;

   step2: 做粗略的broadphase计算阶段,遍历物理世界里面所有的body, 通过AABB包围计算,来快速的判断哪些物体,可能相交;粗略计算,把不会相交的排除掉, 不会相交的就不会改变运动状态;

   step3: narrowphase阶段: 把可能相交的物体,做进一步的精确的计算;根据他们的物理形状,计算出来准确的碰撞点与相关的碰撞信息;

   step4: 基于这些碰撞信息, 我们的物理引擎会计算具体的碰撞信息,关节,摩檫力,阻力等计算, 结合物理的原理,计算出来我们的物理刚体的速度,角速度等运动状态。

   Step5: 根据基于全新的运动状态,把所有运动的物体,向前迭代计算(线性速度,角速度,摩擦力等),计算出这帧新的刚体的位置等信息;

   Step6: Unity Physic 通过 ExportPhysicsWorld System 把物理刚体的位置速度等,同步给节点Entity的LocalTransform组件与PhysicVelocity等组件,这样渲染的entity,就会跟着物理引擎的刚体同步移动;

  DOTS中基于System与SystemGroup 树行结构来决定DOTS中的迭代顺序,这个是DOTS中很重要的一个概念。Unity Physics将上面步骤与逻辑基于ECS设计思想,分别设计了相关的System与System Group,结构如下:

-->FixedStepSimulationSystemGroup:

 -->PhysicsSystemGroup

      -->PhysicsInitializeGroup(System Group)

      -->PhysicsSimulationGroup(SystemGroup)

          -->PhysicsCreateBodyPairsGroup

          -->PhysicsCreateContactsGroup

          -->PhysicsCreateJacobiansGroup

          -->PhysicsSolveAndIntegrateGroup

      -->System: ExportPhysicsWorld

所有物理引擎的迭代计算都是基于FixedStepSimulationSystemGroup,即按照固定的时间间隔来迭代物理仿真,保持物理引擎的一致性与稳定性。所有的物理引擎的仿真计算都放在PysicsSystemGroup下。PysicsSystemGroup包含PhysicsInitializeGroup ,PhysicsSimulationGroup 与一个ExportPhysicsWorld System。上面提到的Step1,在PhysicsInitializeGroup阶段完成, step2~step5在PhysicsSimulationGroup中完成, PhysicsSimulationGroup完成后物理引擎的一帧的迭代计算完成,最后通过ExportPhysicsWorld的System把把物理引擎的内部数据同步到Entity的PhysicsVelocity, LocalTransform等ECS组件。在PhysicsSimulationGroup又有4个subgroup,他们分别对应step2~step5的执行步骤。

Unity Physics碰撞检测事件处理

当PhysicsSimulationGroup的分组执行完成以后,就完成了整个物理引擎的仿真与迭代计算。仿真过程中会产生一个PhysicsWorld,物理世界里面的所有的刚体等相关物理数据(位置,速度等)都可以通过PhysicsWorld得到,最后还被导出到Entity的ECS组件里面。在物理仿真中所有的事件都会被保存到Simulation对象中,这些事件包括了我们常见的碰撞事件与触发器事件。传统模式下我们是通过回调函数来处理的,DOTS模式下我们是在一个System环节内统一来处理这些事件。物理引擎的碰撞与触发事件处理流程如下:

  Step1: 编写一个System处理逻辑,来处理物理事件;

  Step2: 指定好System执行的时机,一定要在PhysicsSimulationGroup之前或者之后,这样才能拿到碰撞事件的数据;

  Step3: 通过编写Job,来遍历当前所有发生的碰撞事件,然后编写每个碰撞事件的处理逻辑;

  Step4: 获取存储事件的Simulation单例,传递给job来进行具体执行;

碰撞事件的处理:

  当所有的模拟迭代计算完成后,会把过程中的所有碰撞事件对存放到Simulation对象中,我们可以通过(SystemBase|SystemAPI|EntityQuery).GetSingleton<SimulationSingleton>().AsSimulation()获取Simulation对象。

要处理所有的碰撞事件,我们先编写一个System用来编写事件处理逻辑,然后编写一个Job,继承自IcollisionEventsJob,这样就可以在Job中遍历所有的碰撞事件,每个碰撞事件都调用Job的Execute函数,在它里面来处理每个碰撞事件的逻辑。代码如下:

[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]

[UpdateBefore(typeof(PhysicsSimulationGroup))] // We are updating before `PhysicsSimulationGroup` - this means that we will get the events of the previous frame

public partial struct GetNumCollisionEventsSystem : ISystem

{

    [BurstCompile]

    public partial struct CountNumCollisionEvents : ICollisionEventsJob

    {

        public NativeReference<int> NumCollisionEvents;

        public void Execute(CollisionEvent collisionEvent)

        {

            NumCollisionEvents.Value++;

        }

    }

    [BurstCompile]

    public void OnUpdate(ref SystemState state)

    {

        NativeReference<int> numCollisionEvents = new NativeReference<int>(0, Allocator.TempJob);

        

        state.Dependency = new CountNumCollisionEvents

        {

            NumCollisionEvents = numCollisionEvents

        }.Schedule(SystemAPI.GetSingleton<SimulationSingleton>());

        // ...

    }

}

触发器事件TriggerEvent处理:

  触发器事件与碰撞事件类似,我们只要编写一个ItriggerEventsJob就可以遍历当前所有的触发器事件了,代码如下:

[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]

[UpdateAfter(typeof(PhysicsSimulationGroup))] // We are updating after `PhysicsSimulationGroup` - this means that we will get the events of the current frame.

public partial struct GetNumTriggerEventsSystem : ISystem

{

    [BurstCompile]

    public partial struct CountNumTriggerEvents : ITriggerEventsJob

    {

        public NativeReference<int> NumTriggerEvents;

        public void Execute(TriggerEvent collisionEvent)

        {

            NumTriggerEvents.Value++;

        }

    }

    [BurstCompile]

    public void OnUpdate(ref SystemState state)

    {

        NativeReference<int> numTriggerEvents = new NativeReference<int>(0, Allocator.TempJob);

        

        state.Dependency = new CountNumTriggerEvents

        {

            NumTriggerEvents = numTriggerEvents

        }.Schedule(SystemAPI.GetSingleton<SimulationSingleton>());

        // ...

    }

}

今天的分享就到这里,文章来源地址https://www.toymoban.com/news/detail-800126.html

到了这里,关于DOTS Unity.Physics物理引擎碰撞事件处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity --- 物理引擎 --- 触发器 与 碰撞器详解

    对第一个条件进行补充 --- 不仅要两者都具有碰撞组件,同时还需要两者的碰撞组件中都没有勾选 Is Trigger属性  1.上一篇文章中说了那么多,其实也可以总结为两个碰撞条件 --- a.两个游戏物体都具有碰撞器组件 ,如果没有的话,连碰撞检测都不会发生,也就没有所谓的碰不

    2024年02月07日
    浏览(46)
  • Unity --- 物理引擎 ---- 刚体RigidBody 与 碰撞器 collider

      1.RigidBody(刚体)的作用是让物体具有物理特性(比如说重力,摩檫力等等) 2.如果想让物体能够与其它物体发生碰撞的话,我们还需要一个组件 --- Colider碰撞器组件 1.上图就是Unity中提供的已经准备好的各种形状的碰撞器组件 2.形成不同形状的碰撞器所需的面数不同,面数

    2024年02月16日
    浏览(40)
  • unity物理碰撞操作方案

    经unity官方网站资料改写整理书写本博客,原网址方案链接如下: Lesson 2.4 - Collision Decisions - Unity Learn 首先  1.先创建两个物体  然后   2.给这两个物体加上Box Collider 组件,并勾选“是触发器”(英文:is 啥啥的) 注意两个都要添加这组件,并且进行相同的操作,都要勾选“

    2024年02月08日
    浏览(36)
  • Unity常用方法--Physics2D.OverlapCircleAll(获取一个圆形区域内所有碰撞器的列表)

    使用方式请直接看参考文献 使用案例 可以通过该方法判断在攻击范围内是否存在敌人,并在存在时,调用敌人组件的内部函数 代码 参考文献   https://docs.unity3d.com/cn/current/ScriptReference/Physics2D.OverlapCircleAll.html

    2024年04月10日
    浏览(37)
  • Unity入门7——物理系统之碰撞检测

    一、刚体 Rigid Body ​ 刚体利用体积(碰撞器 Collider)进行碰撞计算,模拟真实的碰撞效果,产生力的作用 ​ 碰撞产生的必要条件: 两个物体都有碰撞器 Collider 至少一个物体有刚体 Mass:质量 默认为千克,质量越大惯性越大 Drag:空气阻力 根据力移动对象时影响空气阻力大

    2024年02月09日
    浏览(48)
  • Unity UGUI的Physics2DRaycaster (2D物理射线检测)组件的介绍及使用

    Physics2DRaycaster是Unity中的一个UGUI组件,用于在2D场景中进行物理射线检测。它可以检测鼠标或触摸事件在UI元素上的碰撞,并将事件传递给相应的UI元素。 Physics2DRaycaster通过发射一条射线来检测UI元素的碰撞。当射线与UI元素相交时,Physics2DRaycaster会将事件传递给相应的UI元素,

    2024年02月15日
    浏览(49)
  • 2022-04-20 Unity入门7——物理系统之碰撞检测

    一、刚体 Rigid Body ​ 刚体利用体积(碰撞器 Collider)进行碰撞计算,模拟真实的碰撞效果,产生力的作用 ​ 碰撞产生的必要条件: 两个物体都有碰撞器 Collider 至少一个物体有刚体 Mass:质量 默认为千克,质量越大惯性越大 Drag:空气阻力 根据力移动对象时影响空气阻力大

    2023年04月09日
    浏览(41)
  • Unity 2D点击事件、碰撞

    1.事件封装 定义脚本,实现事件相关接口即可 2.点击对象必须要添加BoxCollider2D脚本 3.摄像机上必须添加Physics2DRaycaster脚本 4.GameInputEvent2D 事件必须添加在挂载Physics2DRaycaster的对象及其父类身上。 5.如果要有碰撞或者触发器回调,碰撞其中之一要添加Rigidbody2D脚本,且不能设置

    2024年02月09日
    浏览(37)
  • 【Unity】 基础交互入门(碰撞交互事件OnTriggerEnter和OnCollisionEnter)

    1、在场景中添加两个几何体(例如Cube和Sphere) 2、添加Rigidbody(刚体)component 点击Cube(正方体)对象,在面板找到这个按钮,添加component 搜索Rigidbody 默认状态下collider(碰撞)是被开启的。 3、创建C#脚本,增加OnTriggerEnter事件 4、将shpere(球体)设置为触发器,不需要添加

    2024年02月09日
    浏览(44)
  • Unity基础课程之物理引擎6-关于物理材质的使用和理解

     每个物体都有着不同的摩擦力。光滑的冰面摩擦力很小,而地毯表面的摩擦力则很大。另外每种材料也有着不同的弹性,橡皮表面的弹性大,硬质地面的弹性小。在Unity中这些现象都符合日常的理念。虽然从原理上讲,物体的摩擦力和弹性有着更复杂的内涵,例如普通的钢板

    2024年02月07日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包