分类:Unity、C#、VS2015
创建日期:2016-04-27
一、简介
可以通过编辑器窗口 (Editor Windows) 创建自己在 Unity 中的自定义设计工具。来自EditorWindow (而非 MonoBehaviour )的脚本可以影响 GUI/GUILayout 和 EditorGUI/EditorGUILayout 控件。或者,你可以使用自定义检视器 (Custom Inspectors) 显示游戏对象检视器 (GameObject Inspector) 中的 GUI 控件。
二、自定义编辑器窗口
你可以在应用程序中创建任意数量的自定义窗口。这些窗口和检视器 (Inspector)、场景 (Scene) 及其他内置窗口的作用相似。这非常适合用来为游戏的子系统添加用户界面。
制作一个自定义编辑窗口 (Editor Window) 包括以下几个步骤:
1. 创建一个来自 EditorWindow 的脚本。
2. 使用代码触发窗口自动显示。
3. 执行工具的 GUI 代码。
1、编辑器窗口 (EditorWindow)
为制作编辑器窗口,脚本必须存储在一个叫“Editor”的文件夹中。在这个源自编辑器窗口 (EditorWindow) 的脚本中编写一个类。然后,在内部 OnGUI 函数中编写 GUI 控件。
下面是JavaScript代码示例(当然也可以用C#实现):
class MyWindow extends EditorWindow {
function OnGUI () {
// 实际的窗口代码到这里
}
}
MyWindow.js文件放置于工程中名为“Editor” 的文件夹中。
2、显示窗口
为了在屏幕上显示窗口,需要制作一个用于显示的菜单项。这可以通过创建一个可由 菜单项 (MenuItem) 属性激活的函数来完成。
Unity 中的默认行为是重复使用窗口。所以,再次选择菜单项将显示现有的窗口。可以通过使用EditorWindow.GetWindow 函数实现,下面是JavaScript代码示例(当然你也可以改为用C#实现):
class MyWindow extends EditorWindow {
@MenuItem ("Window/My Window")
static function ShowWindow () {
EditorWindow.GetWindow (MyWindow);
}
function OnGUI () {
// 实际的窗口代码到这里
}
}
这样将创建一个标准的、可停靠的编辑器窗口,该窗口可以将其位置存储在调用之间,可以在自定义布局中使用……等等。如果需要更多地控制创建的窗口,你可以使用 GetWindowWithRect。
3、实施窗口的GUI
该窗口的实际内容通过执行 OnGUI 函数进行渲染。您可以使用游戏 GUI 中使用的 UnityGUI 类( GUI 和GUILayout)。除此之外,Unity还另外提供 了一些 GUI 控件,位于仅编辑器类EditorGUI 和EditorGUILayout中。这些类将添加到常规类中已经可用的控件上,所以你可以随意混合和匹配。
以下 C# 代码显示您如何能将 GUI 元素添加至您的自定义编辑器窗口:
using UnityEditor; using UnityEngine; public class MyWindow : EditorWindow { string myString = "Hello World"; bool groupEnabled; bool myBool = true; float myFloat = 1.23f; // 将名为“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 (); } }
这个示例产生如下所示的窗口:
三、自定义检视器
提高游戏创建速度的关键是为常用组件创建自定义检视器。为了方便举例,我们将使用一个非常简单的脚本,该脚本可以保持对象始终看着一个点。
下面是LookAtPoint.js示例:
var lookAtPoint = Vector3.zero;
function Update () {
transform.LookAt (lookAtPoint);
}
这将保持对象朝向世界坐标空间的一个点。让我们来让它变得酷点!
使编辑器良好运行的第一步是让脚本即使在您未进行游戏测试时也在运行。我们通过为其添加 ExecuteInEditMode 属性来实现:
@script ExecuteInEditMode()
var lookAtPoint = Vector3.zero;
function Update () {
transform.LookAt (lookAtPoint);
}
尝试将脚本添加至您的主相机并在“场景”(Scene) 视图中将其四处拖动。
1、制作一个自定义编辑器
这已经很好了,但是我们可以通过自定义检视器使其更加美观。为此,我们需要为它创建一个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);
}
}
注意该类必须继承自Editor。其中,@CustomEditor 属性报告 Unity 它将作为哪个组件的编辑器。
每当 Unity 显示检视器时,OnInspectorGUI 中的代码都会被执行。因此,你可以在此处放任何 GUI 代码 - 它像游戏的 OnGUI() 一样运行,但却是在检视器内部运行的。编辑器定义可用于访问正被检查的对象的目标属性。
当用户通过检查 GUI.changed 而更改任何值时,EditorUtility.SetDirty 代码将会被执行。
在这种情况下,我们会将向量 3 (Vector3) 字段之一用于变换检视器 (Transform Inspector) - 如下:
还有很多工作没有做,但是我们先到此为止了 - 重头戏还在后面…
2、场景视图添加
你可以通过在自定义编辑器中执行 OnSceneGUI() 来为场景视图 (Scene View) 添加附加代码。在这种情况下,将添加第二个位置控制手柄,使用户可以在场景视图中拖动观察目标点。下面是JavaScript代码示例:
@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() 的调用中。