using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using System.Collections; using System.Collections.Generic; namespace UIWidgets { /// /// Drag support. /// Drop component should implement IDropSupport with same type. /// abstract public class DragSupport : BaseDragSupport, IBeginDragHandler, IEndDragHandler, IDragHandler { /// /// Gets or sets the data. /// Data will be passed to Drop component. /// /// The data. public T Data { get; protected set; } /// /// The Allow drop cursor texture. /// [SerializeField] public Texture2D AllowDropCursor; /// /// The Allow drop cursor hot spot. /// [SerializeField] public Vector2 AllowDropCursorHotSpot = new Vector2(4, 2); /// /// The Denied drop cursor texture. /// [SerializeField] public Texture2D DeniedDropCursor; /// /// The Denied drop cursor hot spot. /// [SerializeField] public Vector2 DeniedDropCursorHotSpot = new Vector2(4, 2); /// /// The default cursor texture. /// [SerializeField] public Texture2D DefaultCursorTexture; /// /// The default cursor hot spot. /// [SerializeField] public Vector2 DefaultCursorHotSpot; /// /// Determines whether this instance can be dragged. /// /// true if this instance can be dragged; otherwise, false. /// Current event data. public virtual bool CanDrag(PointerEventData eventData) { return true; } /// /// Set Data, which will be passed to Drop component. /// /// Current event data. abstract protected void InitDrag(PointerEventData eventData); /// /// Called when drop completed. /// /// true if Drop component received data; otherwise, false. public virtual void Dropped(bool success) { Data = default(T); } /// /// If this object is dragged? /// protected bool IsDragged; /// /// Called by a BaseInputModule before a drag is started. /// /// Current event data. public virtual void OnBeginDrag(PointerEventData eventData) { if (CanDrag(eventData)) { IsDragged = true; InitDrag(eventData); } } /// /// The old drop target. /// protected IDropSupport oldTarget; /// /// The current drop target. /// protected IDropSupport currentTarget; /// /// When draging is occuring this will be called every time the cursor is moved. /// /// Current event data. public virtual void OnDrag(PointerEventData eventData) { if (!IsDragged) { return ; } oldTarget = currentTarget; currentTarget = FindTarget(eventData); if ((oldTarget!=null) && (currentTarget!=oldTarget)) { oldTarget.DropCanceled(Data, eventData); } if (currentTarget!=null) { //set cursor can drop Cursor.SetCursor(AllowDropCursor, AllowDropCursorHotSpot, Utilites.GetCursorMode()); } else { //set cursor fail drop Cursor.SetCursor(DeniedDropCursor, DeniedDropCursorHotSpot, Utilites.GetCursorMode()); } Vector2 point; if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(CanvasTransform as RectTransform, Input.mousePosition, eventData.pressEventCamera, out point)) { return ; } DragPoint.localPosition = point; } List raycastResults = new List(); /// /// Finds the target. /// /// The target. /// Event data. protected IDropSupport FindTarget(PointerEventData eventData) { raycastResults.Clear(); EventSystem.current.RaycastAll(eventData, raycastResults); foreach (var raycastResult in raycastResults) { if (!raycastResult.isValid) { continue ; } #if UNITY_4_6 || UNITY_4_7 var target = raycastResult.gameObject.GetComponent(typeof(IDropSupport)) as IDropSupport; #else var target = raycastResult.gameObject.GetComponent>(); #endif if (target!=null) { return target.CanReceiveDrop(Data, eventData) ? target : null; } } return null; } /// /// Called by a BaseInputModule when a drag is ended. /// /// Current event data. public virtual void OnEndDrag(PointerEventData eventData) { if (!IsDragged) { return ; } var target = FindTarget(eventData); if (target!=null) { target.Drop(Data, eventData); Dropped(true); } else { Dropped(false); } IsDragged = false; Cursor.SetCursor(DefaultCursorTexture, DefaultCursorHotSpot, Utilites.GetCursorMode()); } /// /// This function is called when the MonoBehaviour will be destroyed. /// protected virtual void OnDestroy() { if ((DragPoints!=null) && (CanvasTransform!=null) && (DragPoints.ContainsKey(CanvasTransform))) { DragPoints.Remove(CanvasTransform); } } } }