DOTS Raycast射线检测
1.在使用Raycast之前我们首先要做的是导入引用Havok Physics物理引擎
- Unity Physics
集成Unity Physics方式:
在使用的前提下我们需要给物体加上Physics Shape组件
Physics Shape就等价于BoxCollider碰撞体,不加碰撞体我们是接收不了射线检测的。
Physics Body 则等价于RigidBody重力组件
下面是两种射线检测方式,
一种是主线程正常射线检测
另一种则是使用到了ECS,通过JobSystem把射线的碰撞检测放到了子线程中去跑
第一种
using Unity.Mathematics;
using UnityEngine;
using Unity.Physics;
using Unity.Physics.Systems;
using Unity.Entities;
using Unity.Jobs;
public class RaycastNoraml : MonoBehaviour
{
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
UnityEngine.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Entity entity= Raycast(ray.origin,ray.direction*100);
Debug.Log(entity);
}
}
public Entity Raycast(float3 startPos, float3 endPos)
{
//首先获取物理世界
BuildPhysicsWorld physicsWorld = World.DefaultGameObjectInjectionWorld.GetExistingSystem<BuildPhysicsWorld>();
//然后获取咱们的碰撞世界
CollisionWorld collisionWorld = physicsWorld.PhysicsWorld.CollisionWorld;
RaycastInput raycastInput = new RaycastInput()
{
Start = startPos,
End = endPos,
//声明碰撞过滤器,用来过滤某些层级下的物体是否进行射线检测
//1.Filter = CollisionFilter.Default,
Filter = new CollisionFilter()
{
BelongsTo = ~0u,
CollidesWith = ~0u,
GroupIndex = 0,
}
};
Unity.Physics.RaycastHit raycastHit = new Unity.Physics.RaycastHit();
//发射射线去检测Entity实体
if (collisionWorld.CastRay(raycastInput, out raycastHit))
{
//拿到我们射线击中的entity
Entity entity = physicsWorld.PhysicsWorld.Bodies[raycastHit.RigidBodyIndex].Entity;
return entity;
}
else
{
return Entity.Null;
}
}
}
第二种
using UnityEngine;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Collections;
using Unity.Burst;
using Unity.Physics;
using Unity.Physics.Systems;
public class RaycastSystem : ComponentSystem
{
protected override void OnUpdate()
{
if (Input.GetMouseButtonDown(0))
{
//获取物理世界
BuildPhysicsWorld physicsWorld = World.DefaultGameObjectInjectionWorld.GetExistingSystem<BuildPhysicsWorld>();
NativeArray<RigidBody> rigidBodies = new NativeArray<RigidBody>(1, Allocator.TempJob);
//获取射线发射位置
UnityEngine.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastJonHande raycastJonHande = new RaycastJonHande()
{
mStartPos = ray.origin,
mEndPos = ray.direction,
physicsWorld = physicsWorld.PhysicsWorld,
Bodies = rigidBodies,
};
JobHandle jobHandle = raycastJonHande.Schedule();
jobHandle.Complete();
Debug.Log("射线击中目标" + rigidBodies[0].Entity);
rigidBodies.Dispose();
}
}
[BurstCompile]
public struct RaycastJonHande : IJob
{
public NativeArray<RigidBody> Bodies;
public float3 mStartPos;
public float3 mEndPos;
public PhysicsWorld physicsWorld;
public void Execute()
{
//创建输入
RaycastInput raycastInput = new RaycastInput()
{
Start = mStartPos,
End = mEndPos * 100,
//声明碰撞过滤器,用来过滤某些层级下的物体是否进行射线检测
Filter = new CollisionFilter() {
BelongsTo = ~0u, CollidesWith = ~0u, GroupIndex = 0, }
};
Unity.Physics.RaycastHit raycastHit = new Unity.Physics.RaycastHit();
发射射线去检测Entity实体
if (physicsWorld.CollisionWorld.CastRay(raycastInput, out raycastHit))
{
//拿到我们射线击中的entity
Bodies[0] = physicsWorld.Bodies[raycastHit.RigidBodyIndex];
}
}
}
}