注意:强烈建议使用 UI 工具包 来扩展 Unity 编辑器,因为它提供了一种比 IMGUI 更现代、更灵活、更具可扩展性的解决方案。
为了加快应用程序开发速度,可以为常用的组件创建自定义编辑器。此页面将向您展示如何创建一个简单的脚本,使 游戏对象Unity 场景中的基本对象,可以表示角色、道具、场景、摄像机、路径点等等。游戏对象的功 能由附加在其上的组件定义。 更多信息
参见 术语表 始终看向一个点。
using UnityEngine;
public class LookAtPoint : MonoBehaviour
{
public Vector3 lookAtPoint = Vector3.zero;
void Update()
{
transform.LookAt(lookAtPoint);
}
}
进入播放模式后,您附加脚本的游戏对象现在会朝您设置为“Look At Point”属性的坐标方向。在编写编辑器 脚本一段代码,允许您创建自己的组件、触发游戏事件、随时间推移修改组件属性并以任何您喜欢的方式响应用户输入。 更多信息
参见 术语表 时,通常很有用的是让某些脚本在编辑模式下执行,即您的应用程序未运行时。为此,请将ExecuteInEditMode
属性添加到类中,如下所示
using UnityEngine;
[ExecuteInEditMode]
public class LookAtPoint : MonoBehaviour
{
public Vector3 lookAtPoint = Vector3.zero;
void Update()
{
transform.LookAt(lookAtPoint);
}
}
现在,如果您在编辑器中移动游戏对象,或在 检查器一个 Unity 窗口,显示有关当前选定的游戏对象、资源或项目设置的信息,允许您检查和编辑值。 更多信息
参见 术语表 中更改“Look At Point”的值,则游戏对象会更新其旋转,使其在世界空间中看向目标点。
以上演示了如何在编辑时运行简单的脚本,但是这本身不允许您创建自己的编辑器工具。下一步是为刚刚创建的脚本创建自定义编辑器。
在 Unity 中创建脚本时,默认情况下它继承自 MonoBehaviour,因此它是一个可以附加到游戏对象的组件。当您将组件放置在游戏对象上时,检查器会显示一个默认界面,您可以使用该界面查看和编辑每个公共变量,例如:整数、浮点数或字符串。
这是 LookAtPoint 组件的检查器默认外观
自定义编辑器是一个单独的脚本,它替换此默认布局,并使用您选择的任何编辑器控件。
要为 LookAtPoint 脚本创建自定义编辑器
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(LookAtPoint))]
[CanEditMultipleObjects]
public class LookAtPointEditor : Editor
{
SerializedProperty lookAtPoint;
void OnEnable()
{
lookAtPoint = serializedObject.FindProperty("lookAtPoint");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(lookAtPoint);
serializedObject.ApplyModifiedProperties();
}
}
此类必须继承自Editor。CustomEditor 属性通知 Unity 它应该充当哪个组件的编辑器。CanEditMultipleObjects 属性告诉 Unity 您可以使用此编辑器选择多个对象并同时更改它们。
Unity 在 OnInspectorGUI 中执行代码,它在检查器中显示编辑器。您可以在此处放置任何 GUI 代码,它的工作方式与 OnGUI 相同,但在检查器内部运行。Editor 定义了 target 属性,您可以使用它来访问正在检查的游戏对象。
这是使用新编辑器时 LookAtPoint 组件的检查器外观
这看起来非常相似(尽管“脚本”字段现在不存在,因为编辑器脚本没有添加任何检查器代码来显示它)。
但是,现在您已控制了检查器在编辑器脚本中的显示方式,您可以使用任何您喜欢的代码来布置检查器字段,允许用户调整值,甚至显示图形或其他 视觉元素视觉树的一个节点,它实例化或派生自 C# VisualElement
类。您可以设置外观样式、定义行为并在屏幕上将其显示为 UI 的一部分。 更多信息
参见 术语表。实际上,您在 Unity 编辑器中看到的每个检查器,包括更复杂的检查器,例如 地形场景中的景观。地形游戏对象会向场景添加一个大的平面,您可以使用地形的检查器窗口创建详细的景观。 更多信息
参见 术语表 系统和动画导入设置,都是使用与您在创建自己的自定义编辑器时可以访问的相同的 API 制作的。
这是一个简单的示例,它扩展了您的编辑器脚本以显示一条消息,指示目标点是在游戏对象的上面还是下面
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(LookAtPoint))]
[CanEditMultipleObjects]
public class LookAtPointEditor : Editor
{
SerializedProperty lookAtPoint;
void OnEnable()
{
lookAtPoint = serializedObject.FindProperty("lookAtPoint");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(lookAtPoint);
serializedObject.ApplyModifiedProperties();
if (lookAtPoint.vector3Value.y > (target as LookAtPoint).transform.position.y)
{
EditorGUILayout.LabelField("(Above this object)");
}
if (lookAtPoint.vector3Value.y < (target as LookAtPoint).transform.position.y)
{
EditorGUILayout.LabelField("(Below this object)");
}
}
}
这是使用消息显示目标点是在游戏对象的上面还是下面时 LookAtPoint 组件的检查器外观。
您可以完全访问所有 IMGUI 命令来绘制任何类型的界面,包括使用编辑器窗口内的 摄像机一个组件,它创建场景中特定视点的图像。输出要么绘制到屏幕上,要么捕获为纹理。 更多信息
参见 术语表 渲染场景。
您可以向 场景视图对您正在创建的世界进行交互式查看。您可以使用场景视图选择和放置场景、角色、摄像机、灯光以及所有其他类型的游戏对象。 更多信息
参见 术语表 添加额外的代码。为此,请在您的自定义编辑器中实现 OnSceneGUI。
OnSceneGUI 的工作方式与 OnInspectorGUI 完全相同,只是它在场景视图中运行。为了帮助您创建自己的编辑控件,您可以使用 Handles 类中定义的函数。其中的所有函数都设计用于在 3D 场景视图中工作。
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(LookAtPoint))]
[CanEditMultipleObjects]
public class LookAtPointEditor : Editor
{
SerializedProperty lookAtPoint;
void OnEnable()
{
lookAtPoint = serializedObject.FindProperty("lookAtPoint");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(lookAtPoint);
if (lookAtPoint.vector3Value.y > (target as LookAtPoint).transform.position.y)
{
EditorGUILayout.LabelField("(Above this object)");
}
if (lookAtPoint.vector3Value.y < (target as LookAtPoint).transform.position.y)
{
EditorGUILayout.LabelField("(Below this object)");
}
serializedObject.ApplyModifiedProperties();
}
public void OnSceneGUI()
{
var t = (target as LookAtPoint);
EditorGUI.BeginChangeCheck();
Vector3 pos = Handles.PositionHandle(t.lookAtPoint, Quaternion.identity);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Move point");
t.lookAtPoint = pos;
t.Update();
}
}
}
如果要添加 2D GUI 对象(例如:GUI 或 EditorGUI),则需要将它们包装在对 Handles.BeginGUI() 和 Handles.EndGUI() 的调用中。