hch
2025-07-31 38ed075c317a29496dc10db2ea01d6b674a390d2
Main/Component/UI/Common/BoundedDrag.cs
@@ -10,11 +10,13 @@
using System;
/// <summary>
/// 实现拖拽和缩放功能的组件,支持单指拖拽和双指缩放。
/// </summary>
    public class BoundedDrag : MonoBehaviour, IEndDragHandler, IBeginDragHandler, IDragHandler
    {
        [SerializeField]
        RectTransform m_Target;
    RectTransform m_Target; // 拖拽的目标对象
        public RectTransform target {
            get { return m_Target; }
            set {
@@ -25,24 +27,24 @@
        public RectTransform rectTransform { get { return this.transform as RectTransform; } }
        [SerializeField]
        ScaleRange m_ScaleRange;
    ScaleRange m_ScaleRange; // 缩放范围
        public ScaleRange scaleRange {
            get { return m_ScaleRange; }
            set { m_ScaleRange = value; }
        }
        [SerializeField]
        float m_DefaultScale;
    float m_DefaultScale; // 默认缩放值
        public float defaultScale { get { return m_DefaultScale; } }
        [SerializeField]
        float m_DestScale = 1f;
    float m_DestScale = 1f; // 目标缩放值
        public float destScale {
            get { return m_DestScale; }
            set { m_DestScale = Mathf.Clamp(value, scaleRange.min, scaleRange.max); }
        }
        float refScale = 0f;
    float refScale = 0f; // 用于平滑缩放的参考值
        public float currentScale {
            get {
@@ -54,41 +56,41 @@
        }
        [SerializeField]
        MoveArea m_MoveArea;
    MoveArea m_MoveArea; // 拖拽的边界区域
        public MoveArea moveArea {
            get { return m_MoveArea; }
            set { m_MoveArea = value; }
        }
        [SerializeField]
        Vector2 m_DestPosition = Vector2.zero;
    Vector2 m_DestPosition = Vector2.zero; // 目标位置
        public Vector2 destPosition {
            get { return m_DestPosition; }
            set { m_DestPosition = new Vector2(Mathf.Clamp(value.x, moveArea.Left * destScale, moveArea.Right * destScale), Mathf.Clamp(value.y, moveArea.Bottom * destScale, moveArea.Top * destScale)); }
        }
        Vector3 refPosition = Vector3.zero;
    Vector3 refPosition = Vector3.zero; // 用于平滑移动的参考值
        public Vector2 currentPosition {
            get { return target.anchoredPosition; }
            set { target.anchoredPosition = value; }
        }
        Vector2 startTouchPosition01;
        Vector2 startGroundPosition;
    Vector2 startTouchPosition01; // 单指拖拽的起始触摸位置
    Vector2 startGroundPosition; // 单指拖拽的起始地面位置
        Vector2 lastTouchPosition01;
        Vector2 curTouchPosition01;
        Vector2 lastTouchPosition02;
        Vector2 curTouchPosition02;
    Vector2 lastTouchPosition01; // 双指缩放的上一帧触摸位置1
    Vector2 curTouchPosition01; // 双指缩放的当前帧触摸位置1
    Vector2 lastTouchPosition02; // 双指缩放的上一帧触摸位置2
    Vector2 curTouchPosition02; // 双指缩放的当前帧触摸位置2
        [SerializeField]
        Action m_OnBeginDrag;
    Action m_OnBeginDrag; // 拖拽开始事件
        public Action onBeginDrag {
            get { return m_OnBeginDrag; }
        }
        bool m_Actionable = true;
    bool m_Actionable = true; // 是否可操作
        public bool actionable {
            get { return m_Actionable; }
            set { m_Actionable = value; }
@@ -96,20 +98,22 @@
        private void OnEnable()
        {
            destPosition = currentPosition = Vector3.zero;
        destPosition = currentPosition = Vector3.zero; // 初始化位置
        }
    /// <summary>
    /// 拖拽开始事件处理
    /// </summary>
        public void OnBeginDrag(PointerEventData eventData)
        {
#if UNITY_EDITOR || UNITY_STANDALONE
            if (Input.GetKey(KeyCode.LeftControl) && eventData.button == PointerEventData.InputButton.Left)
            {
                TwoFingerHandleBegin();
            TwoFingerHandleBegin(); // 双指缩放开始
            }
            else if (eventData.button == PointerEventData.InputButton.Left)
            {
                OneFingerHandleBegin(eventData);
            OneFingerHandleBegin(eventData); // 单指拖拽开始
            }
#else
        if (Input.touchCount == 2) {
@@ -119,19 +123,22 @@
            OneFingerHandleBegin(eventData);
        }
#endif
            onBeginDrag?.Invoke();
        onBeginDrag?.Invoke(); // 触发拖拽开始事件
        }
    /// <summary>
    /// 拖拽过程中的事件处理
    /// </summary>
        public void OnDrag(PointerEventData eventData)
        {
#if UNITY_EDITOR || UNITY_STANDALONE
            if (Input.GetKey(KeyCode.LeftControl) && eventData.button == PointerEventData.InputButton.Left)
            {
                TwoFingerHandle();
            TwoFingerHandle(); // 双指缩放
            }
            else if (eventData.button == PointerEventData.InputButton.Left)
            {
                OneFingerHandle(eventData);
            OneFingerHandle(eventData); // 单指拖拽
            }
#else
        if (Input.touchCount == 2) {
@@ -143,10 +150,16 @@
#endif
        }
    /// <summary>
    /// 拖拽结束事件处理
    /// </summary>
        public void OnEndDrag(PointerEventData eventData)
        {
        }
    /// <summary>
    /// 每帧更新,平滑处理缩放和位置
    /// </summary>
        void LateUpdate()
        {
            if (!actionable)
@@ -167,14 +180,19 @@
            }
        }
    /// <summary>
    /// 单指拖拽开始
    /// </summary>
        private void OneFingerHandleBegin(PointerEventData eventData)
        {
            startTouchPosition01 = Vector2.zero;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out startTouchPosition01);
            startGroundPosition = currentPosition;
        }
    /// <summary>
    /// 单指拖拽处理
    /// </summary>
        private void OneFingerHandle(PointerEventData eventData)
        {
            Vector2 localMouse;
@@ -185,6 +203,9 @@
            }
        }
    /// <summary>
    /// 双指缩放处理
    /// </summary>
        private void TwoFingerHandle()
        {
            // 方便PC调试逻辑
@@ -206,6 +227,9 @@
            lastTouchPosition02 = curTouchPosition02;
        }
    /// <summary>
    /// 双指缩放开始
    /// </summary>
        private void TwoFingerHandleBegin()
        {
            // 方便PC调试逻辑
@@ -223,20 +247,26 @@
            lastTouchPosition02 = curTouchPosition02;
        }
    /// <summary>
    /// 缩放范围结构体
    /// </summary>
        [Serializable]
        public struct ScaleRange
        {
            public float min;
            public float max;
        public float min; // 最小缩放值
        public float max; // 最大缩放值
        }
    /// <summary>
    /// 拖拽区域结构体
    /// </summary>
        [Serializable]
        public struct MoveArea
        {
            public float Left;
            public float Right;
            public float Top;
            public float Bottom;
        public float Left; // 左边界
        public float Right; // 右边界
        public float Top; // 上边界
        public float Bottom; // 下边界
            public MoveArea(float _left, float _right, float _top, float _bottom)
            {
@@ -245,6 +275,5 @@
                this.Top = _top;
                this.Bottom = _bottom;
            }
        }
    }