using System.Collections.Generic; using UnityEngine.EventSystems; // ActionDice 처럼 SLUIButton 사용하지 않는 경우용 임시, 남용하지 마시에 namespace Superlazy.UI { public class SLUIDragClick : SLUIComponent, IBeginDragHandler, IDragHandler, IEndDragHandler { public string cancelCommand; public SLValueComparison comparison; private bool draggable = true; private bool dragging = false; private PointerEventData currentPoint; protected override void Validate() { } protected override void Init() { } protected override void Enable() { if (comparison.useCheckValue) comparison.OnEnable(bindParent.BindPath, OnChange); } protected override void Disable() { if (comparison.useCheckValue) comparison.OnDisable(); if (dragging) { EndDrag(); // Dragged == false 체크 이미 되어있음 } } private void OnChange() { if (bindParent.Active == false) return; var result = comparison.Result;// if (draggable && comparison.useCheckValue && comparison.Result == false) { EndDrag(); } draggable = result; } private void BeginDrag() { dragging = true; if (comparison.useCheckValue && comparison.Result == false) return; // ExecuteEvent 때문에 드래그가 무효가 되기 때문에 버튼을 직접 핸들링 ExecuteEvents.Execute(gameObject, currentPoint, ExecuteEvents.pointerClickHandler); } private void Drag() { if (comparison.useCheckValue && comparison.Result == false) return; if (dragging == false) return; } private void EndDrag() { if (dragging == false) return; var pointerData = new PointerEventData(EventSystem.current) { position = currentPoint.position, pointerId = currentPoint.pointerId, pointerEnter = currentPoint.pointerEnter, eligibleForClick = true }; var results = new List(); EventSystem.current.RaycastAll(pointerData, results); var canceled = true; foreach (var result in results) { var targetObject = result.gameObject; if (targetObject == gameObject) // 드래그를 넘 멀리 안했다면 짧은 클릭으로 인식 { dragging = false; return; } else if (targetObject.TryGetComponent(out var target)) { if (target.CanClick()) { // target.Click 에서 EndDrag가 또 불리지 않게끔 미리 드래그 해제 currentPoint = null; SLUIDragButton.currentDragCancelCommand = null; SLUIDragButton.currentDragObject = null; SLUIDragButton.globalDragging = false; target.Click(); canceled = false; } break; } } if (canceled) { SLGame.Command(cancelCommand, bindParent.BindPath); } dragging = false; currentPoint = null; } public void OnBeginDrag(PointerEventData eventData) { currentPoint = eventData; BeginDrag(); } public void OnDrag(PointerEventData eventData) { currentPoint = eventData; Drag(); } public void OnEndDrag(PointerEventData eventData) { currentPoint = eventData; EndDrag(); } } }