扩展编辑器

简介

您可以通过编辑器窗口 (Editor Windows) 创建自己在 Unity 中的自定义设计工具。来自EditorWindow (而非 MonoBehaviour )的脚本可以影响 GUI/GUILayoutEditorGUI/EditorGUILayout 控件。或者,您可以使用自定义检视器 (Custom Inspectors) 显示游戏对象检视器 (GameObject Inspector) 中的 GUI 控件。

编辑器窗口

您可以在应用程序中创建任意数量的自定义窗口。这些窗口和检视器 (Inspector)、场景 (Scene) 及其他内置窗口的作用相似。这非常适合用来为您游戏的子系统添加用户界面。


由 Serious Games Interactive 开发的用来为剧情动画动作编写脚本的自定义编辑器界面 (Custom Editor Interface)

制作一个自定义编辑窗口 (Editor Window) 包括以下几个步骤:

源自编辑器窗口 (EditorWindow)

为制作编辑器窗口,您的脚本必须存储在一个叫“编辑器”的文件夹里。在这个源自编辑器窗口 (EditorWindow) 的脚本中编写一个类。然后,在内部 OnGUI 函数中编写 GUI 控件。

class MyWindow extends EditorWindow {
    function OnGUI () {
        // 实际的窗口代码到这里
    }
}

MyWindow.js - 放置于工程中名为“编辑器”(Editor) 的文件夹中。

显示窗口

为了在屏幕上显示窗口,请制作一个用于显示的菜单项。这可以通过创建一个可由 菜单项 (MenuItem) 属性激活的函数来完成。

Unity 中的默认行为是重复使用窗口(所以,再次选择菜单项将显示现有的窗口。这可以通过使用EditorWindow.GetWindow 函数实现,如下:

class MyWindow extends EditorWindow {
    @MenuItem ("Window/My Window")
    static function ShowWindow () {
        EditorWindow.GetWindow (MyWindow);
    }

    function OnGUI () {
        // 实际的窗口代码到这里
    }
}

显示我的窗口 (MyWindow)

这样将创建一个标准的、可停靠的编辑器窗口,该窗口可以将其位置存储在调用之间,可以在自定义布局中使用,等等。如果需要更多地控制创建的窗口,您可以使用 GetWindowWithRect

实施窗口的 GUI

该窗口的实际内容通过执行 OnGUI 函数进行渲染。您可以使用游戏 GUI 中使用的 UnityGUI 类( GUIGUILayout)。另外,我们还l另外提供 了一些 GUI 控件,位于仅编辑器类EditorGUIEditorGUILayout中。这些类将添加到常规类中已经可用的控件上,所以您可以随意混合和匹配。

以下 C# 代码显示您如何能将 GUI 元素添加至您的自定义编辑器窗口 (EditorWindow):

using UnityEditor;
using UnityEngine;

public class MyWindow : EditorWindow
{
	string myString = "Hello World";
	bool groupEnabled;
	bool myBool = true;
	float myFloat = 1.23f;

	// Ad将名为“My Window”的菜单项添加到窗口菜单
	[MenuItem("Window/My Window")]
	public static void ShowWindow()
	{
		//显示现有窗口实例。如果不存在,请创建一个。
		EditorWindow.GetWindow(typeof(MyWindow));
	}

	void OnGUI()
	{
		GUILayout.Label ("Base Settings", EditorStyles.boldLabel);
		myString = EditorGUILayout.TextField ("Text Field", myString);

		groupEnabled = EditorGUILayout.BeginToggleGroup ("Optional Settings", groupEnabled);
			myBool = EditorGUILayout.Toggle ("Toggle", myBool);
			myFloat = EditorGUILayout.Slider ("Slider", myFloat, -3, 3);
		EditorGUILayout.EndToggleGroup ();
	}
}

这个示例产生如下所示的窗口:


用提供 的示例创建的自定义编辑器窗口。

更多信息,请参阅编辑器窗口页上上的示例和文档。

自定义检视器

提高游戏创建速度的关键是为常用组件创建自定义检视器。为了方便举例,我们将使用一个非常简单的脚本,该脚本可以保持对象始终看着一个点。

var lookAtPoint = Vector3.zero;

function Update () {
    transform.LookAt (lookAtPoint);
}
LookAtPoint.js

这将保持对象朝向世界坐标空间的一个点。让我们来让它变得酷点!

使编辑器良好运行的第一步是让脚本即使在您未进行游戏测试时也在运行。我们通过为其添加 ExecuteInEditMode 属性来实现:

@script ExecuteInEditMode()

var lookAtPoint = Vector3.zero;

function Update () {
    transform.LookAt (lookAtPoint);
}

尝试将脚本添加至您的主相机并在“场景”(Scene) 视图中将其四处拖动。

制作一个自定义编辑器

这已经很好了,但是我们可以通过自定义检视器使其更加美观。为此,我们需要为它创建一个Editor 。在一个名为“编辑器”(Editor) 的文件夹中创建一个叫做 LookAtPointEditor 的 JavaScript。

@CustomEditor (LookAtPoint)
class LookAtPointEditor extends Editor {
    function OnInspectorGUI () {
        target.lookAtPoint = EditorGUILayout.Vector3Field ("Look At Point", target.lookAtPoint);
        if (GUI.changed)
            EditorUtility.SetDirty (target);
    }
}

该类必须源自“编辑器”。@CustomEditor 属性报告 Unity 它将作为哪个组件的编辑器。

每当 Unity 显示检视器时,OnInspectorGUI 中的代码都会被执行。您可以在此处放任何 GUI 代码 - 它像游戏的 OnGUI 一样运行,但却是在检视器内部运行的。编辑器定义可用于访问正被检查的对象的目标属性。

当用户通过检查 GUI.changed 而更改任何值时,EditorUtility.SetDirty 代码将会被执行。

在这种情况下,我们会将向量 3 (Vector3) 字段之一用于变换检视器 (Transform Inspector) - 如下:


为闪亮的检视器欢呼

还有很多工作没有做,但是我们先到此为止了 - 重头戏还在后面…

场景视图添加

您可以通过在自定义编辑器中执行 OnSceneGUI 来为场景视图 (Scene View) 添加附加代码。在这种情况下,我们将添加第二副位置控制手柄,使用户可以在场景视图中拖动观察目标点。

@CustomEditor (LookAtPoint)
class LookAtPointEditor extends Editor {
    function OnInspectorGUI () {
        target.lookAtPoint = EditorGUILayout.Vector3Field ("Look At Point", target.lookAtPoint);
        if (GUI.changed)
            EditorUtility.SetDirty (target);
    }

    function OnSceneGUI () {
        target.lookAtPoint = Handles.PositionHandle (target.lookAtPoint, Quaternion.identity);
        if (GUI.changed)
            EditorUtility.SetDirty (target);
    }
}

OnSceneGUI 的运行和 OnInspectorGUI 一样 - 除了前者是在场景视图中运行的之外。为便于您制作编辑界面,您可以使用手柄 (Handles) 类中定义的函数。其中所有的函数都是为三维场景 (3D Scene) 视图设计的。 如果您想放置二维 GUI 对象(GUI、EditorGUI 和朋友),您需要将这些对象包含在 Handles.BeginGUI() 和 Handles.EndGUI() 的调用中。

Page last updated: 2013-07-01