using Unity.Entities; using Unity.Mathematics; using Unity.Physics; using Unity.Transforms; namespace TinyPhysics.Systems { /// /// Detect when a body is grabbed and move it along the ground /// Use a raycast to find the ground position and place the object above it /// public class PointerDragSystem : PointerSystemBase { private CollisionFilter m_GroundCollisionFilter; protected override void OnCreate() { base.OnCreate(); m_GroundCollisionFilter = new CollisionFilter { BelongsTo = 0xffffffff, CollidesWith = 1u << 4, // Target only ground layer GroupIndex = 0, }; } protected override void OnInputDown(int pointerId, float2 inputPos) { // Get entity under pointer var pointerRaycastHit = GetPointerRaycastHit(inputPos, m_CollisionFilter); var pointerEntity = pointerRaycastHit.Entity; // Only target entities with Draggable component if (pointerEntity != Entity.Null && HasComponent(pointerEntity)) { var draggable = GetComponent(pointerEntity); draggable.PointerId = pointerId; draggable.IsDragged = true; SetComponent(pointerEntity, draggable); } } protected override void OnInputMove(int pointerId, float2 inputPos, float2 inputDelta) { Entities.ForEach((ref Draggable draggable, ref Translation translation) => { if (draggable.IsDragged && draggable.PointerId == pointerId) { // Find ground position under pointer var pointerRaycastHit = GetPointerRaycastHit(inputPos, m_GroundCollisionFilter); if (pointerRaycastHit.Entity != Entity.Null) { // Update dragged entity position translation.Value = pointerRaycastHit.Position; translation.Value.y += 0.5f; // TODO: Get actual distance from ground } } }).WithoutBurst().Run(); } protected override void OnInputUp(int pointerId, float2 inputPos) { Entities.ForEach((ref Draggable draggable) => { if (draggable.IsDragged && draggable.PointerId == pointerId) { draggable.IsDragged = false; } }).Run(); } protected override void OnInputCanceled(int pointerId) { Entities.ForEach((ref Draggable draggable) => { if (draggable.IsDragged && draggable.PointerId == pointerId) { draggable.IsDragged = false; } }).Run(); } } }