首页 > 其他分享 >Unity编辑器扩展秘籍-实现一个可拖放的List

Unity编辑器扩展秘籍-实现一个可拖放的List

时间:2024-09-20 21:25:50浏览次数:7  
标签:false EventType List private height Unity headerRect public 拖放


using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;

namespace yaojz
{
    public class DroppableListView
    {
        private List<DroppableItem> _datas = new List<DroppableItem>();
        private Vector2 scrollPosition;
        private bool _editable;
        private const float DEFAULT_EMPTY_HEIGHT = 20f; // 默认空列表的高度

        private Func< Object[],bool> OnCheckDrop;
        private float? _height;
        
        public readonly GUIStyle headerBackground = "RL Header";
        private readonly GUIStyle emptyHeaderBackground = "RL Empty Header";
        public readonly GUIStyle elementBackground = "RL Element";

        public string Title { get; private set; }

        public DroppableListView(string title,bool editable = false,float? height = null)
        {
            _editable = editable;
            _height = height;
            Title = title;
        }

        private void DoListHeader(Rect headerRect)
        {
            DrawHeaderBackground(headerRect);
            EditorGUI.LabelField(headerRect, Title);
        }
        
        public void DoLayout()
        {
            // do the custom or default header GUI
            GUIStyle boxStyle = new GUIStyle(EditorStyles.helpBox);
            var headerHeight = 20;
            Rect headerRect = GUILayoutUtility.GetRect(0, headerHeight, GUILayout.ExpandWidth(true));
            DoListHeader(headerRect);
            
            if (_datas.Count == 0)
            {
                // 如果列表为空,显示提示信息
                Rect emptyRect = EditorGUILayout.GetControlRect(false, DEFAULT_EMPTY_HEIGHT);
                EditorGUI.HelpBox(emptyRect, "List is Empty", MessageType.Info);
                DragDrop();
            }
            else
            {
                if (_height != null)
                {
                    scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition,boxStyle,GUILayout.Height(_height.Value));
                }
                else
                {
                    scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition,boxStyle);    
                }
                
                for (int i = 0; i < _datas.Count; i++)
                {
                    EditorGUILayout.BeginHorizontal();
                    DrawCustomTextField(i);
                    if (GUILayout.Button("Remove", GUILayout.Width(60)))
                    {
                        _datas.RemoveAt(i);
                        GUIUtility.ExitGUI();
                    }
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.EndScrollView();
                DragDrop();
            }
        }

        private void DragDrop()
        {
            Event evt = Event.current;
            Rect dropArea = GUILayoutUtility.GetLastRect();
            switch (evt.type)
            {
                case EventType.DragUpdated:
                case EventType.DragPerform:
                    OnDragPerform(dropArea,evt);
                    break;
            }
        }

        private void OnDragPerform(Rect dropArea,Event evt)
        {
            if (!dropArea.Contains(evt.mousePosition))
                return;
            var canDrop = OnCheckDrop?.Invoke(DragAndDrop.objectReferences) ?? true;
            if (!canDrop)
            {
                return;
            }
            DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
            if (evt.type == EventType.DragPerform)
            {
                DragAndDrop.AcceptDrag();
                foreach (var draggedObject in DragAndDrop.objectReferences)
                {
                    Debug.Log(draggedObject.GetType());
                    // if (PrefabUtility.GetPrefabAssetType(draggedObject) != PrefabAssetType.NotAPrefab)
                    // {
                    //     
                    // }
                    var item = new DroppableItem();
                    item.Data = draggedObject;
                    item.Name = draggedObject.name;
                    _datas.Add(item);
                }
            }
        }

        private void DrawCustomTextField(int index)
        {
            EditorGUILayout.LabelField(_datas[index].Name);
            var rect = EditorGUILayout.GetControlRect();
            // if (Event.current.type == EventType.Repaint)
            // {
            //     elementBackground.Draw(rect,false,false,false,false);    
            // }
            // Event currentEvent = Event.current;
            // if (currentEvent.type == EventType.DragUpdated || currentEvent.type == EventType.DragPerform)
            // {
            //     if (textFieldRect.Contains(currentEvent.mousePosition))
            //     {
            //         DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
            //         if (currentEvent.type == EventType.DragPerform)
            //         {
            //             DragAndDrop.AcceptDrag();
            //             foreach (var draggedObject in DragAndDrop.objectReferences)
            //             {
            //                 // _datas[index] = AssetDatabase.GetAssetPath(draggedObject);
            //             }
            //         }
            //         currentEvent.Use();
            //     }
            // }
        }
        
        // draw the default header background
        public void DrawHeaderBackground(Rect headerRect)
        {
            if (Event.current.type == EventType.Repaint)
            {
                // We assume that a height smaller than 5px means a header with no content
                if (headerRect.height < 5f)
                {
                    emptyHeaderBackground.Draw(headerRect, false, false, false, false);
                }
                else
                {
                    headerBackground.Draw(headerRect, false, false, false, false);
                }
            }
        }
    }

    public class DroppableItem
    {
        public Object Data;
        public string Name;
    }
}

标签:false,EventType,List,private,height,Unity,headerRect,public,拖放
From: https://www.cnblogs.com/terrynoya/p/18423302

相关文章

  • 一文详解Unity下RTMP推送|轻量级RTSP服务|RTSP|RTMP播放模块说明
    技术背景好多开发者,对Unity下的模块,不甚了解,实际上,除了Windows/Linux/Android/iOSNativeSDK,大牛直播SDK发布了Unity环境下的RTMP推流|轻量级RTSP服务(Windows平台+Linux平台+Android平台)和RTMP|RTSP直播播放(Windows、Linux、Android和iOS平台全覆盖)低延迟的解决方案。目前,大牛直播......
  • VBA技术资料MF198:禁用下拉拖放
    我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解,从简单的入门、到入门后的提高、到数据库、到字典、到WordVBA的应用、到高级......
  • Java怎么把多个对象的list的数据合并
    在Java中,将多个对象的列表数据合并成一个新的列表可以通过多种方式实现。假设有一个List的列表,每个列表都包含相同类型的对象,可以使用StreamAPI或传统的循环来实现这一目标。示例代码假设我们有一个User类:publicclassUser{privateStringname;privateinta......
  • Qt拖拽事件详解,拖放数据传递
    1.QT拖拽事件分为两类。(1)电脑上的文件拖入程序,在程序上放下文件Drop;例如将视频拖入程序进行播放,将图片突入程序进行展示;(2)程序中界面内部拖放,例如将组织树中的监控点拖入播放窗口进行播放;将一个表格中的人员拖入另外一个表格等;将QTreeview中的item拖动位置,移到不同的组织下;或者将......
  • unity调用java静态方法
    在uni-app中使用NFC功能,可以通过调用微信小程序的NFCAPI(目前只在微信小程序中有效)。uni-app是多平台框架,而NFC功能的具体实现依赖于微信小程序的NFCAPI。以下是如何在uni-app中使用NFC功能,包括发现NFC设备、连接以及写入数据的详细步骤。​前置条件确保已经......
  • 【春秋招必看】Unity相关笔试面试题(内有完整答案)第二期
    欢迎来到光光的奇妙冒险,我是你们的煎饼光子老师。今天是我们的第二期笔试面试题总结。C#部分:1、请说说你认为C#中==和Equals的区别是什么?答案:(1).==是运算符,Equals是万物之父Object中的虚方法,子类可重写(2).Equals一般在子类中重写后用于比较两个对象中内容是否相同......
  • en造数据结构与算法C# 用Unity实现简单的群组行为算法 之 对齐
    en造数据结构与算法C#用Unity实现简单的群组行为算法之聚集-CSDN博客en造数据结构与算法C#用Unity实现简单的群组行为算法之聚集-CSDN博客演示思路1.检测自然是沿用前两节的检测范围2.对齐朝向对齐朝向就是邻居鸟的forward加起来再除总数得到平均数3.对齐速度......
  • torch.distributed.DistNetworkError: The server socket has failed to listen on an
    解决方案是在torchrun中添加参数--master_port改变masterport。且注意这个参数一定要加在要跑的文件即src/entry_point/train.py之前,否则会被忽略。引用:https://juejin.cn/post/7260668104752775228我的代码是:torchrun--nproc_per_node1--master_port29501-mtraining.......
  • Java Map和List常见操作
    Javamap详解-用法、遍历、排序、常用API等-Java初级码农-博客园(cnblogs.com)//创建实例importjava.util.*;publicclassListDemo{publicstaticvoidmain(String[]args){List<String>arrayList=newArrayList<>();//创建ArrayList实例......
  • Java中List接口的学习
    List接口目录List接口ArrayListLinkedListVector(过时)Stack(过时)ArrayListArrayList就是动态数组,它提供了①动态的增加和减少元素②实现了ICollection和IList接口③灵活的设置数组的大小ArrayList是一个其容量能够动态增长的动态数组。它继承了AbstractList,实现了List、Ran......