using UnityEngine; using UnityEngine.EventSystems; namespace Rokid.UXR.Interaction { /// /// Draggable 拖拽组件 /// [RequireComponent(typeof(RayInteractable))] public class Draggable : MonoBehaviour, IGesDragToTarget, IGesBeginDrag, IGesEndDrag, IBezierCurveDrag, IRayBeginDrag, IRayDrag, IRayEndDrag, IMouseBeginDrag, IMouseDrag, IMouseEndDrag, IDraggable { [SerializeField, Tooltip("拖拽平滑速度")] private int smoothSpeed = 10; [SerializeField, Tooltip("跟随该拖拽物体对象")] private Transform followObj; private Vector3 offsetPos; private Vector3 allDelta; private Vector3 oriPos; private Vector3 hitLocalPos; private Vector3 hitLocalNormal; private bool dragging = false; private bool gesDragging = false; private void Start() { if (followObj != null) { offsetPos = transform.InverseTransformPoint(followObj.position); } } public void OnGesBeginDrag(PointerEventData eventData) { allDelta = Vector3.zero; oriPos = transform.position; hitLocalPos = transform.InverseTransformPoint(eventData.pointerCurrentRaycast.worldPosition); hitLocalNormal = transform.InverseTransformVector(eventData.pointerCurrentRaycast.worldNormal); dragging = true; gesDragging = true; } public void OnGesEndDrag() { allDelta = Vector3.zero; dragging = false; gesDragging = false; } public void OnRayBeginDrag(PointerEventData eventData) { allDelta = Vector3.zero; oriPos = transform.position; hitLocalPos = transform.InverseTransformPoint(eventData.pointerCurrentRaycast.worldPosition); hitLocalNormal = transform.InverseTransformVector(eventData.pointerCurrentRaycast.worldNormal); dragging = true; } public void OnRayDrag(Vector3 delta) { allDelta += delta; } public void OnRayEndDrag() { allDelta = Vector3.zero; dragging = false; } public void OnMouseBeginDrag(PointerEventData eventData) { allDelta = Vector3.zero; oriPos = transform.position; hitLocalPos = transform.InverseTransformPoint(eventData.pointerCurrentRaycast.worldPosition); hitLocalNormal = transform.InverseTransformVector(eventData.pointerCurrentRaycast.worldNormal); dragging = true; } public void OnMouseRayDrag(Vector3 delta) { allDelta += delta; } public void OnMouseEndDrag() { allDelta = Vector3.zero; dragging = false; } public bool IsEnablePinchBezierCurve() { return true; } public bool IsEnableGripBezierCurve() { return true; } public bool IsInBezierCurveDragging() { return dragging; } public Vector3 GetBezierCurveEndPoint() { return transform.TransformPoint(hitLocalPos); } public Vector3 GetBezierCurveEndNormal() { return transform.TransformVector(hitLocalNormal).normalized; } private void Update() { if (dragging && !gesDragging) { Vector3 targetPos = oriPos + allDelta; this.transform.position = Vector3.Slerp(this.transform.position, targetPos, Time.deltaTime * smoothSpeed); // this.transform.position = Utils.SmoothTo(this.transform.position, targetPos, 0.01f, Time.deltaTime); if (followObj != null) followObj.position = transform.TransformPoint(offsetPos); } } public void OnGesDragToTarget(Vector3 targetPos) { this.transform.position = Vector3.Slerp(this.transform.position, targetPos, Time.deltaTime * smoothSpeed); // this.transform.position = Utils.SmoothTo(this.transform.position, targetPos, 0.01f, Time.deltaTime); if (followObj != null) followObj.position = transform.TransformPoint(offsetPos); } } }