UnityEditor TreeView 拖拽至场景实现教程
要实现从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元素拦截。
原文地址: http://www.cveoy.top/t/topic/lMwF 著作权归作者所有。请勿转载和采集!