ProjectDDD/Assets/_Datas/SLShared/SLUnity/SLUI/SLUIDragClick.cs
2025-06-17 20:47:57 +09:00

139 lines
4.0 KiB (Stored with Git LFS)
C#

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<RaycastResult>();
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<SLUIDragClickTarget>(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();
}
}
}