Unity DOTS中的物理系统即Unity.Physics,这里使用一个简单的demo(小球相撞效果),来说明一下 碰撞 Collision。
1、创建两个sphere(注意,要去掉ShpereCollider),添加Physics Shape,ShapeType 选择 Sphere,PhysicsShape 选择Collide Raise Collision Events。新建CollisionFilter类型Sphere和Plane,然后设置 BelongsTo = Sphere,设置CollidesWith = Sphere, Plane;添加 Physics Body。
2、创建三个plane(注意,要去掉MeshCollider),添加Physics Shape,ShapeType 选择 Plane,PhysicsShape 选择Collide。然后设置 CollisionFilter, BelongsTo = Plane,设置CollidesWith = Sphere;添加 Physics Body,MotionType设为Kinematic。
3、小球碰撞,触发逻辑
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using Unity.Physics;
using Unity.Collections;
using Unity.Physics.Systems;public class PhysicalSystem : SystemBase
{
private BuildPhysicsWorld buildPhysicsWorld;//物理系统的准备工作,将TriggerCollisionEvents传递给Jobprivate StepPhysicsWorld stepPhysicsWorld;//物理系统的准备工作,将TriggerCollisionEvents传递给Jobprotected override void OnCreate(){
buildPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();stepPhysicsWorld = World.GetOrCreateSystem<StepPhysicsWorld>();}protected override void OnUpdate(){
ColliderJob colliderJob = new ColliderJob(){
velocitys = GetComponentDataFromEntity<PhysicsVelocity>()};Dependency = colliderJob.Schedule(stepPhysicsWorld.Simulation, ref buildPhysicsWorld.PhysicsWorld, Dependency);}
}public struct ColliderJob : ICollisionEventsJob
{
public ComponentDataFromEntity<PhysicsVelocity> velocitys;public void Execute(CollisionEvent collisionEvent){
if (velocitys.HasComponent(collisionEvent.EntityA) && IsSphere(collisionEvent.EntityA, "Sphere")){
if (velocitys.HasComponent(collisionEvent.EntityB) && IsSphere(collisionEvent.EntityB, "Sphere")){
var velocityA = velocitys[collisionEvent.EntityA];var dirA = -math.sign(velocityA.Linear.x);//Debug.Log("dirA = " + dirA);velocityA.Linear.x = dirA * 20;velocitys[collisionEvent.EntityA] = velocityA;var velocityB = velocitys[collisionEvent.EntityB];var dirB = -math.sign(velocityB.Linear.x);//Debug.Log("dirB = " + dirB);velocityB.Linear.x = dirB * 20;velocitys[collisionEvent.EntityB] = velocityB;}}}public bool IsSphere(Entity entity, string name){
return World.DefaultGameObjectInjectionWorld.EntityManager.GetName(entity) == name;}
}