unity中 使用IDragHandler拖动交换子物体

using DG.Tweening;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using VRSightCheck.Scripts;

public class SwapPanel : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    ///


    /// 是否已经响应拖拽
    ///

    public static bool isDrag = false;

    private List items;  // 子物体数组

    private int currentIndex = -1;  // 当前需要交换位置的子物体索引

    ///


    /// 开始点击gameobject
    ///

    private GameObject mStartGo;

    ///


    /// 开始坐标
    ///

    private Vector3 startPos = Vector3.zero;

    ///


    /// 结束点击gameobject
    ///

    private GameObject mEndGo;

    ///


    /// 结束坐标
    ///

    private Vector3 endPos = Vector3.zero;

    ///


    /// 是否正在移动
    ///

    private bool isMove = false;

    ///


    /// 移动时间
    ///

    private const float MOVE_TIME = 0.2f;

    ///


    /// 动画
    ///

    private Tweener[] tws;

    ///


    /// 成功换位置事件
    ///

    private Action ChangeSucAct;

    private void Awake()
    {
        items = new List();
        currentIndex = -1;
        mStartGo = null;
        startPos = Vector3.zero;
        mEndGo = null;
        endPos = Vector3.zero;
        isMove = false;
        tws = new Tweener[3];
        ChangeSucAct = new Action(ChangeSuc);
    }

    ///


    /// 清除子物体
    ///

    public void ClearItem()
    {
        items.Clear();
    }

    ///


    /// 添加子物体
    ///

    public void AddItem(RectTransform it)
    {
        items.Add(it);
    }

    ///


    /// 设置委托
    ///

    ///
    public void SetChangeSucAct(Action act)
    {
        ChangeSucAct = act;
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        //Debug.Log("OnBeginDrag=======================>");
        if (items.Count == 0 || isMove || isDrag) return;
        // 检查触摸点是否在另一个子物体上,并根据索引信息交换两个子物体的位置
        List results = new List();
        EventSystem.current.RaycastAll(eventData, results);
        if (results.Count == 0) return;
        List gos = new List();
        for (int i = 0; i < results.Count; i++)
        {
            gos.Add(results[i].gameObject);
        }
        // 检查触摸点是否在其中一个子物体上
        for (int i = 0; i < items.Count; i++)
        {
            //if (RectTransformUtility.RectangleContainsScreenPoint(items[i], eventData.position, UICanvasManager.Instance.CameraCanvas))
            if(gos.Contains(items[i].gameObject))
            {
                currentIndex = i;
                mStartGo = items[i].gameObject;
                startPos = items[i].position;

                isDrag = true;
                break;
            }
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        //Debug.Log("OnDrag=======================>");
        if (items.Count == 0 || isMove) return;
        
        if (currentIndex >= 0)
        {
            // 根据触摸点的移动距离计算出当前子物体应该移动的位置
            Vector2 offset = eventData.delta / transform.localScale.x;
            if(items.Count > currentIndex)
            {
                items[currentIndex].anchoredPosition += offset;
            }
        }
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        //Debug.Log("OnEndDrag=======================>");
        if (items.Count == 0 || isMove || mStartGo == null) return;
        
        for (int i = 0; i < items.Count; i++)
        {
            if (i != currentIndex && RectTransformUtility.RectangleContainsScreenPoint(items[i], eventData.position , UICanvasManager.Instance.CameraCanvas))
            {
                mEndGo = items[i].gameObject;
                endPos = items[i].position;
                Change();
                break;
            }
        }
        if (mEndGo == null)
        {
            MoveBack();
        }
        currentIndex = -1;

        isDrag = false;
    }

    ///


    /// 清除开始点击gameObject
    ///

    void ClearStartGo()
    {
        if (mStartGo == null) return;
        mStartGo.transform.localScale = Vector3.one;
        mStartGo = null;
    }


    ///


    /// 未成功换位置,返回
    ///

    void MoveBack()
    {
        isMove = true;

        tws[0] = mStartGo.transform.DOMove(startPos, MOVE_TIME);

        tws[0].SetEase(Ease.Linear);
        tws[0].OnComplete( () =>{
            ClearStartGo();
            isMove = false;
        });

        if (mEndGo != null)
        {
            mEndGo = null;
        }
    }

    ///


    /// 替换位置
    ///

    void Change()
    {
        isMove = true;
        int idx = mStartGo.transform.GetSiblingIndex();
        mStartGo.transform.SetSiblingIndex(mEndGo.transform.GetSiblingIndex());
        mEndGo.transform.SetSiblingIndex(idx);

        tws[1] = mStartGo.transform.DOMove(endPos, MOVE_TIME);
        tws[1].SetEase(Ease.Linear);
        tws[2] = mEndGo.transform.DOMove(startPos, MOVE_TIME);
        tws[2].SetEase(Ease.Linear);
        tws[2].OnComplete(() => {
            Debug.Log("替换位置================>" + ChangeSucAct);
            ChangeSucAct(mStartGo, mEndGo);
            ClearStartGo();
            isMove = false;
            mEndGo = null;
        });
    }


    private void OnDestroy()
    {
        //停止动画
        for (int i = 0; i < tws.Length; i++)
        {
            if (tws[i] != null) tws[i].Kill();
        }
    }


    private void ChangeSuc(GameObject arg1, GameObject arg2)
    {

    }
}

你可能感兴趣的:(unity,ui,c#,游戏引擎)