using System; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.UI; [RequireComponent(typeof(CanvasGroup))] public class uGUIDraggingObject : UIBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IEventSystemHandler { private RectTransform rectTrans { get { return this.m_RectTrans; } } private CanvasGroup canvasGroup { get { return this.m_CanvasGroup; } } public UnityEvent onSelectEvent { get { return this.m_OnSelectEvent; } set { this.m_OnSelectEvent = value; } } public UnityEvent onDeselectEvent { get { return this.m_OnDeselectEvent; } set { this.m_OnDeselectEvent = value; } } public UnityEvent onClickEvent { get { return this.m_OnClickEvent; } set { this.m_OnClickEvent = value; } } public bool isScaling { get { return this.m_IsScaling; } set { this.m_IsScaling = value; } } public float minSizeX { get { return this.m_MinSizeX; } set { this.m_MinSizeX = Mathf.Clamp(value, 20f, float.PositiveInfinity); } } public float minSizeY { get { return this.m_MinSizeY; } set { this.m_MinSizeY = Mathf.Clamp(value, 20f, float.PositiveInfinity); } } protected override void Start() { base.Start(); this.m_StartPosition = this.rectTrans.anchoredPosition; this.m_StartSizeDelta = this.rectTrans.sizeDelta; if (this.rectTrans.parent) { int siblingIndex = base.transform.GetSiblingIndex(); uGUIDraggingObject[] componentsInChildren = this.rectTrans.parent.GetComponentsInChildren(); int num = componentsInChildren.Length - 1; if (componentsInChildren[num] == this) { this.canvasGroup.alpha = 1f; this.canvasGroup.interactable = true; } else { this.canvasGroup.alpha = 0.5f; this.canvasGroup.interactable = false; this.CreateBlocker(); } } this.m_IsStarted = true; } public void ResetTransform() { if (!this.m_IsStarted) { return; } this.rectTrans.anchoredPosition = this.m_StartPosition; this.rectTrans.sizeDelta = this.m_StartSizeDelta; } public void OnPointerDown(PointerEventData eventData) { if (eventData.button != PointerEventData.InputButton.Left) { return; } this.ChangeWindowColor(); EventSystem.current.SetSelectedGameObject(base.gameObject); this.OnBeginDrag(eventData); } public void OnDrag(PointerEventData eventData) { if (!this.m_IsMove) { return; } if (eventData.button != PointerEventData.InputButton.Left) { return; } Vector3 b = eventData.position - eventData.pressPosition; b.Scale(this.m_ReciprocalCanvasScale); Rect rect = this.rectTrans.rect; Vector3 vector = this.m_ClickPosition; if (this.m_IsDragRight) { rect.width = this.m_ClickRect.width + b.x; vector -= new Vector3(b.x * 0.5f, b.y, 0f); } if (this.m_IsDragLeft) { rect.width = this.m_ClickRect.width - b.x; vector -= new Vector3(b.x * 0.5f, b.y, 0f); } if (this.m_IsDragBottom) { rect.height = this.m_ClickRect.height + b.y; vector -= new Vector3(b.x, b.y * 0.5f, 0f); } if (this.m_IsDragTop) { rect.height = this.m_ClickRect.height - b.y; vector -= new Vector3(b.x, b.y * 0.5f, 0f); } if (rect.size.x < this.minSizeX) { rect.width = this.minSizeX; float num = Mathf.Sign(b.x); vector.x -= (b.x - num * (this.m_ClickRect.width - this.minSizeX)) * 0.5f; } if (rect.size.y < this.minSizeY) { rect.height = this.minSizeY; float num2 = Mathf.Sign(b.y); vector.y -= (b.y - num2 * (this.m_ClickRect.height - this.minSizeY)) * 0.5f; } if ((this.m_IsDragRight || this.m_IsDragLeft) && (this.m_IsDragTop || this.m_IsDragBottom)) { vector += b; } vector += b; this.rectTrans.localPosition = vector; this.rectTrans.sizeDelta = rect.size; } public void OnPointerUp(PointerEventData eventData) { if (eventData.button != PointerEventData.InputButton.Left) { return; } this.m_IsDragRight = false; this.m_IsDragLeft = false; this.m_IsDragTop = false; this.m_IsDragBottom = false; this.m_IsMove = false; } public void OnPointerClick(PointerEventData eventData) { if (this.onClickEvent != null) { this.onClickEvent.Invoke(); } } public void OnBeginDrag(PointerEventData eventData) { if (this.m_IsMove) { return; } Canvas rootCanvas = base.GetComponentInParent().rootCanvas; RectTransform component = rootCanvas.GetComponent(); this.UpdateReciprocalCanvasScale(); Vector2 position = eventData.position; Rect rect = this.rectTrans.rect; Vector2 vector = position - new Vector2(this.rectTrans.localPosition.x, this.rectTrans.localPosition.y); vector = position - RectTransformUtility.WorldToScreenPoint(rootCanvas.worldCamera, this.rectTrans.position); vector.Scale(this.m_ReciprocalCanvasScale); this.m_ClickPosition = this.rectTrans.localPosition; this.m_ClickRect = rect; if (this.isScaling) { float dragScalingRange = this.m_DragScalingRange; this.m_IsDragRight = (Mathf.Abs(vector.x - rect.xMax) < dragScalingRange); this.m_IsDragLeft = (Mathf.Abs(vector.x - rect.xMin) < dragScalingRange); this.m_IsDragBottom = (Mathf.Abs(vector.y - rect.yMax) < dragScalingRange); this.m_IsDragTop = (Mathf.Abs(vector.y - rect.yMin) < dragScalingRange); } this.m_IsMove = true; } public void OnEndDrag(PointerEventData eventData) { this.OnPointerUp(eventData); } private void UpdateReciprocalCanvasScale() { Canvas rootCanvas = base.GetComponentInParent().rootCanvas; UIRoot componentInParent = base.GetComponentInParent(); Vector2 v = new Vector2((float)componentInParent.manualWidth, (float)componentInParent.manualHeight); Vector2 vector = new Vector2((float)rootCanvas.worldCamera.pixelWidth, (float)rootCanvas.worldCamera.pixelHeight); float num = v.y / v.x; float num2 = vector.y / vector.x; float num3 = num2 / num; this.m_ReciprocalCanvasScale = v; this.m_ReciprocalCanvasScale.x = this.m_ReciprocalCanvasScale.x / vector.x; this.m_ReciprocalCanvasScale.y = this.m_ReciprocalCanvasScale.y / vector.y; if (num3 > 1f) { this.m_ReciprocalCanvasScale.y = this.m_ReciprocalCanvasScale.y * num3; } else { this.m_ReciprocalCanvasScale.x = this.m_ReciprocalCanvasScale.x / num3; } } private void ChangeWindowColor() { this.rectTrans.SetAsLastSibling(); if (this.canvasGroup) { this.canvasGroup.alpha = 1f; this.canvasGroup.interactable = true; } if (this.onSelectEvent != null) { this.onSelectEvent.Invoke(); } if (this.rectTrans.parent) { uGUIDraggingObject[] componentsInChildren = this.rectTrans.parent.GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { if (!(componentsInChildren[i] == this)) { CanvasGroup canvasGroup = componentsInChildren[i].canvasGroup; if (canvasGroup) { canvasGroup.alpha = 0.5f; canvasGroup.interactable = false; componentsInChildren[i].CreateBlocker(); } if (componentsInChildren[i].m_OnDeselectEvent != null) { componentsInChildren[i].m_OnDeselectEvent.Invoke(); } } } } } private void CreateBlocker() { if (this.m_Blocker) { return; } GameObject blocker = new GameObject("[uGUIDraggingObject] Raycast Blocker"); this.m_Blocker = blocker; RectTransform rectTransform = blocker.AddComponent(); rectTransform.SetParent(this.rectTrans, false); rectTransform.anchorMin = Vector3.zero; rectTransform.anchorMax = Vector3.one; rectTransform.sizeDelta = Vector2.zero; Canvas canvas = blocker.AddComponent(); canvas.overrideSorting = true; canvas.sortingOrder = base.GetComponentInParent().sortingOrder + 10; CanvasGroup canvasGroup = blocker.AddComponent(); canvasGroup.ignoreParentGroups = true; canvasGroup.interactable = true; canvasGroup.blocksRaycasts = true; GraphicRaycaster graphicRaycaster = blocker.AddComponent(); graphicRaycaster.blockingObjects = GraphicRaycaster.BlockingObjects.All; Image image = blocker.AddComponent(); image.color = Color.clear; uGUIDraggingObject.RaycastBlocker raycastBlocker = blocker.AddComponent(); raycastBlocker.onPointerDown = delegate(PointerEventData data) { UnityEngine.Object.Destroy(blocker); this.m_Blocker = null; this.OnPointerDown(data); }; } private void OnReset() { Canvas canvas = base.GetComponent(); if (!canvas) { canvas = base.gameObject.AddComponent(); canvas.overrideSorting = false; uGUIUtility.SetLayer(base.gameObject, LayerMask.NameToLayer("NGUI"), true); } GraphicRaycaster graphicRaycaster = base.GetComponent(); if (!graphicRaycaster) { graphicRaycaster = base.gameObject.AddComponent(); graphicRaycaster.blockingObjects = GraphicRaycaster.BlockingObjects.All; } CanvasGroup exists = base.GetComponent(); if (!exists) { exists = base.gameObject.AddComponent(); } if (!this.m_RectTrans) { this.m_RectTrans = base.GetComponent(); } if (!this.m_CanvasGroup) { this.m_CanvasGroup = base.GetComponent(); } } [SerializeField] [HideInInspector] private RectTransform m_RectTrans; [SerializeField] [HideInInspector] private CanvasGroup m_CanvasGroup; [SerializeField] [Tooltip("選択されたときのイベント")] private UnityEvent m_OnSelectEvent; [SerializeField] [Tooltip("別のウィンドウが選択されたときのイベント")] private UnityEvent m_OnDeselectEvent; [SerializeField] [Tooltip("クリックされるたびに呼ばれるイベント")] private UnityEvent m_OnClickEvent; [SerializeField] [Tooltip("端のドラッグによるスケーリングを行うかどうか")] private bool m_IsScaling; [SerializeField] private float m_MinSizeX = 100f; [SerializeField] private float m_MinSizeY = 100f; private bool m_IsDragRight; private bool m_IsDragLeft; private bool m_IsDragTop; private bool m_IsDragBottom; private float m_DragScalingRange = 15f; private bool m_IsMove; private Vector3 m_ClickPosition = Vector3.zero; private Rect m_ClickRect; private Vector3 m_StartPosition; private Vector2 m_StartSizeDelta; private Vector3 m_ReciprocalCanvasScale; private GameObject m_Blocker; private bool m_IsStarted; private class RaycastBlocker : MonoBehaviour, IPointerDownHandler, IEventSystemHandler { public void OnPointerDown(PointerEventData eventData) { if (this.onPointerDown != null) { this.onPointerDown(eventData); } } public Action onPointerDown; } }