using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; [RequireComponent(typeof(Image))] public class Dragable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { protected GameObject m_DraggingIcon; protected RectTransform m_DraggingPlane; public virtual void OnBeginDrag(PointerEventData eventData) { var canvas = FindInParents(gameObject); if (canvas == null) return; // We have clicked something that can be dragged. // What we want to do is create an icon for this. m_DraggingIcon = new GameObject("icon"); m_DraggingIcon.transform.SetParent(canvas.transform, false); m_DraggingIcon.transform.SetAsLastSibling(); m_DraggingIcon.layer = LayerMask.NameToLayer("Ignore Raycast"); var image = m_DraggingIcon.AddComponent(); image.sprite = GetComponent().sprite; image.SetNativeSize(); m_DraggingPlane = canvas.transform as RectTransform; SetDraggedPosition(eventData); } public virtual void OnDrag(PointerEventData data) { if (m_DraggingIcon != null) SetDraggedPosition(data); } protected virtual void SetDraggedPosition(PointerEventData data) { var rt = m_DraggingIcon.GetComponent(); Vector3 globalMousePos; if (RectTransformUtility.ScreenPointToWorldPointInRectangle(m_DraggingPlane, data.position, data.pressEventCamera, out globalMousePos)) { rt.position = globalMousePos; rt.rotation = m_DraggingPlane.rotation; } } public virtual void OnEndDrag(PointerEventData eventData) { Destroy(m_DraggingIcon); m_DraggingIcon = null; } static public T FindInParents(GameObject go) where T : Component { if (go == null) return null; var comp = go.GetComponent(); if (comp != null) return comp; Transform t = go.transform.parent; while (t != null && comp == null) { comp = t.gameObject.GetComponent(); t = t.parent; } return comp; } }