Unity 革命性技术DOST入门五 Physics触发器

前言

上一篇说到在DOTS中使用射线检测功能:

Unity 革命性技术DOST入门四 Raycast射线检测

说到物理世界那么肯定少不掉我们最为常用的碰撞检测,这算是我们开发中很常用的一个功能了,他的性能也是非常重要的,所以Unity为DOTS专门准备了一个新的物理世界,哦不,应该算是两个把,,一个叫Unity.Physics 另一个则叫Havok Physics,那么咱们这里就先用第一种,第二种咱们后面再说

Unity.Physics使用介绍

首先是Physics中最重要且最常用的两个Authoring

1.Physics Body

2.Physics Shape

Physics Bodyd 对标的是Rigid Body

Physics Shape则对标的则是Collider

时代在进步,技术也在进步,这些本来稳如泰山的组件也有了新的替代品,随着时代的变化也将会渐渐被淘滩掉,优胜劣汰,在所难免。
在这里插入图片描述
从上图我们可以看到,他们需要通过Convert To Entity(把物体转到Entity下,原本的GameObject则会被删除掉) 进行转换以得到在Entity世界下与其相对应的Entity以及与之所对应的ECSComponent
如下图:
在这里插入图片描述
下面我们看一下触发器该如何使用

Unity.Physics触发器使用介绍

首先是 Collision Response属性

很重要 一共有四种

  • Collide:默认的值,可以进行物理模拟但不会产生任何事件

  • CollideRaiseCollisionEvents:碰撞器。可以进行物理模拟并且可以产生CollisionEvent碰撞事件供我们使用

  • RaiseTriggerEvents:触发器。和以前Collider上的IsTrigger勾选一样,可以产生TriggerEvent供我们使用

  • None:什么都不做,但是可以用于射线的检测

下面是触发器使用的案例:

首先我们在使用触发器之前来回顾一下 物理事件触发的原理:

首先是必须两个物体都有Collider 在DOTS中则是Physics Shape, 且必须有一个物体带有刚体组件(物理系统)DOTS中则是Physics Body。

我们要想在DOTS中得到触发器事件,就要借助 Unity.Physics命名空间下的ITriggerEventsJob方法
如下:

private struct YourTriggerJob: ITriggerEventsJob
{
    
    
     public void Execute(TriggerEvent triggerEvent){
    
    }
}

我们要想获取碰撞事件,同理介借助 ICollisionEventsJob

private struct YourTriggerJob: ICollisionEventsJob
{
    
    
     public void Execute(CollisionEvent collisionEvent){
    
    }
}

这里讲下触发器,碰撞器原理是一样的

触发器中最为核心的肯定是咱们的TriggerEvent

因为咱们可以通过TriggerEvent得到咱们碰撞到的物体

看下TriggerEvent都有什么

namespace Unity.Physics
{
    
    
    public struct TriggerEvent
    {
    
    
        public Entity EntityB {
    
     get; }
        public Entity EntityA {
    
     get; }
        public int BodyIndexB {
    
     get; }
        public int BodyIndexA {
    
     get; }
        public ColliderKey ColliderKeyB {
    
     get; }
        public ColliderKey ColliderKeyA {
    
     get; }
        [Obsolete("Entities has been deprecated. Use EntityA and EntityB directly. (RemovedAfter 2020-08-01)")]
        public EntityPair Entities {
    
     get; }
        [Obsolete("BodyIndices has been deprecated. Use BodyIndexA and BodyIndexB directly. (RemovedAfter 2020-08-01)")]
        public BodyIndexPair BodyIndices {
    
     get; }
        [Obsolete("ColliderKeys has been deprecated. Use ColliderKeyA and ColliderKeyB directly. (RemovedAfter 2020-08-01)")]
        public ColliderKeyPair ColliderKeys {
    
     get; }
    }
}

可以看到我们的EntityA 和Entity B 这两个Entity,这两个Entity则是碰撞到的 A 物体和 B 物体。

那么我们该怎么区分 AB 这两个物体哪一个是我们想要触发事件的呢?

我们可以通过HasComponent判断这个物体是否包含我们的 物理系统(Physics Body)

回顾一下碰撞的原则的后半段,在DOTS中必须有一个物体带有 物理系统(Physics Body)

那这里有人要问了 如果两个物体都带有物理系统,会怎么办?

那不好意思,A和B的逻辑都会执行,当然也可以通过在哪个物体上放Physics Body来决定哪个物体去触发事件

下面贴上源码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Jobs;
using Unity.Entities;
using Unity.Physics;
using Unity.Burst;
using Unity.Physics.Systems;

public class TriggerSystem : JobComponentSystem
{
    
    
    // 构建的物理世界
   private BuildPhysicsWorld mPhysicsWorld;
    //梯度物理世界
    private StepPhysicsWorld mSetpPhysicsWorld;
    protected override void OnCreate()
    {
    
    
        //构建获取咱们的物理世界  
        mPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();
        //获取梯度物理世界
        mSetpPhysicsWorld = World.GetOrCreateSystem<StepPhysicsWorld>();
    }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
    
    
        TriggerJob triggerJob = new TriggerJob
        {
    
    
            //获取物理世界的所有物理组件数据 赋值过去
            mPhysicsVelocityGroup = GetComponentDataFromEntity<PhysicsVelocity>(),
        };
        return triggerJob.Schedule(mSetpPhysicsWorld.Simulation, ref mPhysicsWorld.PhysicsWorld,inputDeps);
    }


    /// <summary>
    /// 创建触发器
    /// </summary>
    [BurstCompile]
    public struct TriggerJob : ITriggerEventsJob
    {
    
    
        //触发器组
        public ComponentDataFromEntity<PhysicsVelocity> mPhysicsVelocityGroup;
        public void Execute(TriggerEvent triggerEvent)
        {
    
    
            // 这里我们通过HasComponent判断哪个Entity上有物理系统(Physics Body)  
            //注意:触发器触发条件是两个物体都有Collider 在DOTS中则是Physics Shape,
            //且必须有一个物体带有刚体组件(物理系统)DOTS中则是Physics Body。
            if (mPhysicsVelocityGroup.HasComponent(triggerEvent.EntityA))
            {
    
    
                PhysicsVelocity velocity = mPhysicsVelocityGroup[triggerEvent.EntityA];
                velocity.Linear.y = 5;
                mPhysicsVelocityGroup[triggerEvent.EntityA] = velocity;
            }
            //这里注意:如果两个物体都具有物理系统 那么这两个逻辑都会执行 所以我们尽量遵循原则
            //也可以通过哪个物体上放Physics Body来决定哪个物体去触发事件
            if (mPhysicsVelocityGroup.HasComponent(triggerEvent.EntityB))
            {
    
    
                PhysicsVelocity velocity = mPhysicsVelocityGroup[triggerEvent.EntityB];
                velocity.Linear.y = 5;
                mPhysicsVelocityGroup[triggerEvent.EntityB] = velocity;
            }
        }
    }
}

所以我们还是要尽量去遵守原则

下一篇:Unity 革命性技术DOST入门六 Animation动画系统

DOTS入门视屏教程

猜你喜欢

转载自blog.csdn.net/qq_42461824/article/details/113100097