TH1/Unity/Assets/Scripts/TH1_UI/UIBlockCameraDrag.cs

138 lines
4.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using UnityEngine;
using UnityEngine.EventSystems;
// 为避免潜在的冲突和更清晰的逻辑,建议将类名稍作更改,以反映其新功能
// 例如UIMouseBlocker或者就保持 UIBlockCameraDrag 也可以,只要功能上能理解
public class UIBlockCameraDrag : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
private const float DragThresholdPixels = 10f;
public static bool IsPointerOnUI = false;
public static bool ShouldBlockDrag = false;
public static bool MoveEvent = false;
public static bool DownUpEvent = false;
public static Vector3 PointerDownScreenPosition;
public static Vector3 ClickScreenPosition;
public static Vector3 DragOrigin;
public static Vector3 MoveVector;
private static UIBlockCameraDrag _activeBlocker;
private bool _isPointerInside;
//是否ban点击
public bool BanClick = false;
public static void ResetState()
{
IsPointerOnUI = false;
ShouldBlockDrag = false;
MoveEvent = false;
DownUpEvent = false;
PointerDownScreenPosition = Vector3.zero;
ClickScreenPosition = Vector3.zero;
DragOrigin = Vector3.zero;
MoveVector = Vector3.zero;
_activeBlocker = null;
}
private static Vector3 GetMouseWorldPosition()
{
var mainCamera = Camera.main;
return mainCamera == null ? Vector3.zero : mainCamera.ScreenToWorldPoint(Input.mousePosition);
}
private void ClearDragState()
{
if (_activeBlocker != null && _activeBlocker != this)
return;
if (_activeBlocker == this)
_activeBlocker = null;
ShouldBlockDrag = false;
MoveEvent = false;
DragOrigin = Vector3.zero;
MoveVector = Vector3.zero;
}
public void OnPointerEnter(PointerEventData eventData)
{
_isPointerInside = true;
IsPointerOnUI = true;
}
public void OnPointerExit(PointerEventData eventData)
{
_isPointerInside = false;
IsPointerOnUI = false;
ClearDragState();
}
public void OnPointerDown(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
// OnPointerEnter may be missed after reconnect/reset if the cursor is already on this raycast target.
_isPointerInside = true;
IsPointerOnUI = true;
_activeBlocker = this;
ShouldBlockDrag = true;
MoveEvent = false;
PointerDownScreenPosition = eventData.position;
ClickScreenPosition = PointerDownScreenPosition;
DragOrigin = GetMouseWorldPosition();
MoveVector = Vector3.zero;
}
}
public void OnPointerUp(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
if ((_activeBlocker == this || _isPointerInside) && !MoveEvent && !BanClick)
{
ClickScreenPosition = PointerDownScreenPosition;
DownUpEvent = true;
}
IsPointerOnUI = _isPointerInside;
ClearDragState();
}
}
private void OnDisable()
{
_isPointerInside = false;
if (_activeBlocker == this)
ResetState();
}
public void Update()
{
if (ShouldBlockDrag)
{
if (!MoveEvent)
{
var screenDelta = (Vector2)Input.mousePosition - (Vector2)PointerDownScreenPosition;
if (screenDelta.magnitude <= DragThresholdPixels)
{
MoveVector = Vector3.zero;
return;
}
MoveEvent = true;
DragOrigin = GetMouseWorldPosition();
MoveVector = Vector3.zero;
return;
}
MoveVector = DragOrigin - GetMouseWorldPosition();
if (MoveVector.sqrMagnitude <= Mathf.Epsilon)
{
MoveVector = Vector3.zero;
}
}
}
}