unity实现背包拖拽排序

在原本的滑动列表上层创建一个相同的dragParentRect层,用来在拖拽时将GameObject置顶,创建一个空白的空物体用来占位,_parentRect就是滑动列表的Content。

cs 复制代码
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class EntryNodeGo : MonoBehaviour,IBeginDragHandler, IDragHandler, IEndDragHandler
{
    public TMP_Text msg;
    public Button editBtn;
    public Button deleteBtn;
    public GameObject blank;

    private int _id;
    private int _index;
    private Vector2 _dragOffset;
    private RectTransform _rectTransform;
    private RectTransform _parentRect;
    private RectTransform _dragParentRect;
    private GameObject _blank;
    private Vector2 _cellSize;
    private Vector2 _spacing;
    private RectOffset _padding;
    private const int HorizontalCount = 4;

    private void Start()
    {
        _rectTransform = transform as RectTransform;
        _parentRect = transform.parent as RectTransform;
        GridLayoutGroup gridLayoutGroup = _parentRect.GetComponent<GridLayoutGroup>();
        _padding = gridLayoutGroup.padding;
        _cellSize = gridLayoutGroup.cellSize;
        _spacing = gridLayoutGroup.spacing;
    }
    
    public void Init(int id, int index,RectTransform dragParentRect)
    {
        _id = id;
        _index = index;
        _dragParentRect = dragParentRect;
        msg.text = $"Entry {_id} \nindex {_index}";
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (eventData.button == PointerEventData.InputButton.Left)
        {
            ExecuteEvents.ExecuteHierarchy(transform.parent.gameObject, eventData, ExecuteEvents.beginDragHandler);
        }
        else if (eventData.button == PointerEventData.InputButton.Right)
        {
            _index = transform.GetSiblingIndex();
            RectTransformUtility.ScreenPointToLocalPointInRectangle(
                _dragParentRect, eventData.position, eventData.pressEventCamera, out var localPoint);
            _dragOffset = (Vector2)_rectTransform.localPosition - localPoint;
            _dragOffset.y += _parentRect.localPosition.y;
            transform.SetParent(_dragParentRect, true);
            _blank = Instantiate(blank,_parentRect);
            _blank.transform.SetSiblingIndex(_index);
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (eventData.button == PointerEventData.InputButton.Left)
        {
            ExecuteEvents.ExecuteHierarchy(transform.parent.gameObject, eventData, ExecuteEvents.dragHandler);
        }
        else if (eventData.button == PointerEventData.InputButton.Right)
        {
            // 算出新的局部位置
            RectTransformUtility.ScreenPointToLocalPointInRectangle(
                _dragParentRect, eventData.position, eventData.pressEventCamera, out var localPoint);
            Vector2 newPos = localPoint + _dragOffset;

            // 限制在父物体矩形范围内
            Rect rect = _dragParentRect.rect;
            Vector3 min = rect.min;
            Vector3 max = rect.max;

            // 考虑子物体自身尺寸
            Vector2 halfSize = _rectTransform.rect.size * 0.5f;

            newPos.x = Mathf.Clamp(newPos.x, min.x + halfSize.x, max.x - halfSize.x);
            newPos.y = Mathf.Clamp(newPos.y, min.y + halfSize.y, max.y - halfSize.y);

            _rectTransform.localPosition = newPos;

            int horizontalIndex = (int)((newPos.x - _padding.left)/(_cellSize.x + _spacing.x));
            float y = Mathf.Abs(newPos.y) + _cellSize.y/2;
            int verticalIndex = Mathf.RoundToInt((y - _padding.top + _parentRect.localPosition.y)/(_cellSize.y + _spacing.y));
            verticalIndex = Mathf.Max(1, verticalIndex);
            _index = (verticalIndex - 1) * HorizontalCount + horizontalIndex;
            _blank.transform.SetSiblingIndex(_index);
        }
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        if (eventData.button == PointerEventData.InputButton.Left)
        {
            ExecuteEvents.ExecuteHierarchy(transform.parent.gameObject, eventData, ExecuteEvents.endDragHandler);
        }
        else if (eventData.button == PointerEventData.InputButton.Right)
        {
            Destroy(_blank);
            transform.SetParent(_parentRect, true);
            transform.SetSiblingIndex(_index);
        }
    }
}

滑动列表结构如下:

相关推荐
叶帆14 天前
【YFIOs】用C#开发硬件之设备上云
开发语言·unity·c#
久数君14 天前
AI三维建模工具“造形家”:地理场景三维化的高效解决方案
unity·glb·ai算法·ai三维建模工具·地图框选·造形家·城市建筑模型
会思考的猴子14 天前
Unity VFX 属性 Postion 和 TargetPostion
unity
hai31524754314 天前
九章编程法 · 猜数字游戏 (GW-BASIC 重构版) *
人工智能·microsoft·游戏引擎·游戏程序
心前阳光15 天前
Unity资源导入之自动化资源导入
unity·自动化·游戏引擎
心前阳光15 天前
Unity之2021.3.45f2c1发布安卓程序遇到的问题
android·unity·游戏引擎
纪纯15 天前
PicoVR Unity Integration SDK 3.4 常用交互API
unity·游戏引擎·vr·pico
龙智DevSecOps解决方案15 天前
3A 游戏优化技术栈:如何打通引擎级分析工具与 DevOps 持续集成管线?
unity·性能优化·游戏开发·技术美术·perforce·unrealengine
葛兰岱尔15 天前
从 SolidWorks 到 Three.js,从 Inventor 到 Unity——制造业CAD模型“几何-语义一体化“转换,不再是天方夜谭!
开发语言·javascript·unity
鼎艺创新科技15 天前
三维电子沙盘中OSGB倾斜摄影数据的加载与渲染
游戏引擎·cocos2d