要实现从TreeView拖拽至场景中,需要使用UnityEditor内置的DragAndDrop类。以下是一个简单的示例代码:

using UnityEditor;
using UnityEngine;

public class MyTreeViewItem
{
    public string name;
    public GameObject prefab;
    public bool isDraggable;
}

public class MyTreeView : EditorWindow
{
    private MyTreeViewItem[] items;
    private int selectedItemIndex = -1;

    [MenuItem("Window/My Tree View")]
    public static void ShowWindow()
    {
        GetWindow<MyTreeView>("My Tree View");
    }

    private void OnGUI()
    {
        if (items == null)
        {
            items = new MyTreeViewItem[]
            {
                new MyTreeViewItem { name = "Cube", prefab = Resources.Load<GameObject>("Cube"), isDraggable = true },
                new MyTreeViewItem { name = "Sphere", prefab = Resources.Load<GameObject>("Sphere"), isDraggable = true },
                new MyTreeViewItem { name = "Empty", prefab = null, isDraggable = false }
            };
        }

        for (int i = 0; i < items.Length; i++)
        {
            Rect itemRect = new Rect(10, 10 + i * 20, position.width - 20, 20);

            if (selectedItemIndex == i)
            {
                EditorGUI.DrawRect(itemRect, Color.blue);
            }

            GUIContent content = new GUIContent(items[i].name);

            if (items[i].isDraggable)
            {
                DragAndDrop.PrepareStartDrag();
                DragAndDrop.objectReferences = new UnityEngine.Object[] { items[i].prefab };
                DragAndDrop.StartDrag(content);
            }

            if (itemRect.Contains(Event.current.mousePosition))
            {
                if (Event.current.type == EventType.MouseDown)
                {
                    selectedItemIndex = i;
                }
            }

            GUI.Label(itemRect, content);
        }
    }
}

在这个示例中,我们创建了一个包含三个项的TreeView。前两个项是可拖拽的物体,第三个项是一个不可拖拽的空项。

当用户点击一个可拖拽项时,我们会设置selectedItemIndex为该项的索引。在OnGUI中,我们用选定项的背景颜色高亮显示该项。

当用户拖拽一个可拖拽项时,我们将该项的prefab添加到DragAndDrop.objectReferences中,并调用DragAndDrop.StartDrag启动拖拽操作。

在场景中接收拖拽操作通常是通过实现EditorDropHandler接口来完成的。以下是一个示例实现:

using UnityEditor;
using UnityEngine;

public class MySceneView : SceneView, IEditorDropHandler
{
    public void OnEditorDrop(Object[] droppedObjects)
    {
        foreach (Object obj in droppedObjects)
        {
            GameObject prefab = obj as GameObject;

            if (prefab != null)
            {
                GameObject instance = Instantiate(prefab);
                instance.transform.position = SceneView.lastActiveSceneView.camera.transform.position;
            }
        }
    }
}

在这个示例中,我们创建了一个自定义的SceneView,并实现了IEditorDropHandler接口。当用户在该场景视图中拖拽一个物体时,OnEditorDrop方法会被调用,我们在其中实例化该物体,并将其放置在场景视图的相机位置。

最后,我们需要将这个SceneView注册到UnityEditor的事件系统中,以便它能够接收拖拽操作。这可以通过使用EditorApplication.update事件来完成:

[InitializeOnLoad]
public class MyEditor
{
    static MyEditor()
    {
        EditorApplication.update += () =>
        {
            if (SceneView.lastActiveSceneView != null)
            {
                SceneView.lastActiveSceneView.SetSceneViewFiltering(true);
                SceneView.lastActiveSceneView.editorWindow.DropZoneGUI();
            }
        };
    }
}

这个示例中,我们使用了EditorApplication.update事件,检查当前活动的场景视图是否存在,如果存在则调用其DropZoneGUI方法来注册拖拽操作处理器。注意,我们还调用了SetSceneViewFiltering方法来启用场景视图过滤器,以便拖拽操作不会被其他UI元素拦截。

UnityEditor TreeView 拖拽至场景实现教程

原文地址: http://www.cveoy.top/t/topic/lMwF 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录