using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; namespace UIWidgets { public abstract class DragSupport : BaseDragSupport, IBeginDragHandler, IEndDragHandler, IDragHandler, IEventSystemHandler { [SerializeField] public Texture2D AllowDropCursor; [SerializeField] public Vector2 AllowDropCursorHotSpot = new Vector2(4f, 2f); [SerializeField] public Texture2D DeniedDropCursor; [SerializeField] public Vector2 DeniedDropCursorHotSpot = new Vector2(4f, 2f); [SerializeField] public Texture2D DefaultCursorTexture; [SerializeField] public Vector2 DefaultCursorHotSpot; protected bool IsDragged; protected IDropSupport oldTarget; protected IDropSupport currentTarget; private List raycastResults = new List(); public T Data { get; protected set; } public virtual bool CanDrag(PointerEventData eventData) { return true; } protected abstract void InitDrag(PointerEventData eventData); public virtual void Dropped(bool success) { Data = default(T); } public virtual void OnBeginDrag(PointerEventData eventData) { if (CanDrag(eventData)) { IsDragged = true; InitDrag(eventData); } } public virtual void OnDrag(PointerEventData eventData) { if (IsDragged) { oldTarget = currentTarget; currentTarget = FindTarget(eventData); if (oldTarget != null && currentTarget != oldTarget) { oldTarget.DropCanceled(Data, eventData); } if (currentTarget != null) { Cursor.SetCursor(AllowDropCursor, AllowDropCursorHotSpot, Utilites.GetCursorMode()); } else { Cursor.SetCursor(DeniedDropCursor, DeniedDropCursorHotSpot, Utilites.GetCursorMode()); } Vector2 localPoint; if (RectTransformUtility.ScreenPointToLocalPointInRectangle(base.CanvasTransform as RectTransform, Input.mousePosition, eventData.pressEventCamera, out localPoint)) { base.DragPoint.localPosition = localPoint; } } } protected IDropSupport FindTarget(PointerEventData eventData) { raycastResults.Clear(); EventSystem.current.RaycastAll(eventData, raycastResults); foreach (RaycastResult raycastResult in raycastResults) { if (raycastResult.isValid) { IDropSupport component = raycastResult.gameObject.GetComponent>(); if (component != null) { return (!component.CanReceiveDrop(Data, eventData)) ? null : component; } } } return null; } public virtual void OnEndDrag(PointerEventData eventData) { if (IsDragged) { IDropSupport dropSupport = FindTarget(eventData); if (dropSupport != null) { dropSupport.Drop(Data, eventData); Dropped(true); } else { Dropped(false); } IsDragged = false; Cursor.SetCursor(DefaultCursorTexture, DefaultCursorHotSpot, Utilites.GetCursorMode()); } } protected virtual void OnDestroy() { if (BaseDragSupport.DragPoints != null && base.CanvasTransform != null && BaseDragSupport.DragPoints.ContainsKey(base.CanvasTransform)) { BaseDragSupport.DragPoints.Remove(base.CanvasTransform); } } } }