Files
aibis-dream/Assets/Scripts/FixSystem/DraggableUI.cs
T
2026-07-26 23:44:10 +08:00

83 lines
2.1 KiB
C#

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class DraggableUI : MonoBehaviour, IDragHandler, IPointerDownHandler
{
public RectTransform target;
public Button button;
private bool isLocked = false;
private Vector3 _dragOffset;
private float _dragScreenZ;
private void Awake()
{
LockDrag();
}
public void OnPointerDown(PointerEventData eventData)
{
if (isLocked) return;
Camera cam = ResolveCamera(eventData);
if (cam == null) return;
// 记录指针与物体的世界空间偏移,避免拖动开始时物体跳到指针中心。
_dragScreenZ = cam.WorldToScreenPoint(transform.position).z;
Vector3 pointerWorld = ScreenToWorld(cam, eventData.position, _dragScreenZ);
_dragOffset = transform.position - pointerWorld;
}
public void OnDrag(PointerEventData eventData)
{
if (isLocked) return;
Camera cam = ResolveCamera(eventData);
if (cam == null) return;
Vector3 pointerWorld = ScreenToWorld(cam, eventData.position, _dragScreenZ);
Vector3 move = pointerWorld + _dragOffset;
move.z = transform.position.z;
transform.position = move;
}
void Update()
{
if (target == null || button == null) return;
float distance = Vector3.Distance(transform.position, target.position);
if (distance <= 1 && !isLocked)
{
button.interactable=true;
}
else
{
button.interactable=false;
}
}
public void LockDrag()
{
isLocked = true;
}
public void UnlockDrag()
{
isLocked = false;
}
private static Camera ResolveCamera(PointerEventData eventData)
{
if (eventData != null && eventData.pressEventCamera != null)
return eventData.pressEventCamera;
return Camera.main;
}
private static Vector3 ScreenToWorld(Camera cam, Vector2 screenPosition, float screenZ)
{
return cam.ScreenToWorldPoint(new Vector3(screenPosition.x, screenPosition.y, screenZ));
}
}