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

Copy
using System; using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; namespace yaojz { public class DroppableListView { private IList _datas; private Vector2 scrollPosition; private bool _editable; private const float DEFAULT_EMPTY_HEIGHT = 20f; // 默认空列表的高度 public Func<Object[],bool> OnCheckDrop; public Action<Object> OnDropItem; 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(IList datas,string title,bool editable = false,float? height = null) { _datas = datas; _editable = editable; _height = height; Title = title; } public IList Datas => _datas; 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 dropObject in DragAndDrop.objectReferences) { // if (PrefabUtility.GetPrefabAssetType(draggedObject) != PrefabAssetType.NotAPrefab) // { // // } OnDropItem?.Invoke(dropObject); } } } private void DrawCustomTextField(int index) { EditorGUILayout.LabelField(_datas[index].ToString()); 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); } } } } }
posted @   jeoyao  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示