从中派生自定义编辑器的基类。使用此类可为对象创建您自己的自定义检视面板和编辑器。
设想一个 MyPlayer 脚本,其中包含盔甲和伤害的变量,以及对枪支 GameObject 的引用。
using UnityEngine; using System.Collections;
// This is not an editor script. public class MyPlayer : MonoBehaviour { public int armor = 75; public int damage = 25; public GameObject gun;
void Update() { // Update logic here... } }
使用自定义编辑器时,可以在检视面板中更改脚本外观,正如下图所示:
\
检视面板中的自定义编辑器。
您可以使用 CustomEditor 属性将编辑器附加到自定义组件。
可通过多种方式设计自定义编辑器。
如果您希望编辑器支持多对象编辑,可以使用 CanEditMultipleObjects 属性。
与直接修改脚本变量相比,使用 SerializedObject 和 SerializedProperty
系统进行编辑更为有利,因为这会自动处理多对象编辑、撤消和预制件重载。如果使用此方法,用户可以在层次结构窗口中选择多个资源并一次性更改所有资源的值。
using UnityEditor; using UnityEngine; using System.Collections;
// Custom Editor using SerializedProperties. // Automatic handling of multi-object editing, undo, and prefab overrides. [CustomEditor(typeof(MyPlayer))] [CanEditMultipleObjects] public class MyPlayerEditor : Editor { SerializedProperty damageProp; SerializedProperty armorProp; SerializedProperty gunProp;
void OnEnable() { // Setup the SerializedProperties. damageProp = serializedObject.FindProperty ("damage"); armorProp = serializedObject.FindProperty ("armor"); gunProp = serializedObject.FindProperty ("gun"); }
public override void OnInspectorGUI() { // Update the serializedProperty - always do this in the beginning of OnInspectorGUI. serializedObject.Update ();
// Show the custom GUI controls. EditorGUILayout.IntSlider (damageProp, 0, 100, new GUIContent ("Damage"));
// Only show the damage progress bar if all the objects have the same damage value: if (!damageProp.hasMultipleDifferentValues) ProgressBar (damageProp.intValue / 100.0f, "Damage");
EditorGUILayout.IntSlider (armorProp, 0, 100, new GUIContent ("Armor"));
// Only show the armor progress bar if all the objects have the same armor value: if (!armorProp.hasMultipleDifferentValues) ProgressBar (armorProp.intValue / 100.0f, "Armor");
EditorGUILayout.PropertyField (gunProp, new GUIContent ("Gun Object"));
// Apply changes to the serializedProperty - always do this in the end of OnInspectorGUI. serializedObject.ApplyModifiedProperties (); }
// Custom GUILayout progress bar. void ProgressBar (float value, string label) { // Get a rect for the progress bar using the same margins as a textfield: Rect rect = GUILayoutUtility.GetRect (18, 18, "TextField"); EditorGUI.ProgressBar (rect, value, label); EditorGUILayout.Space (); } }
或者,如果不需要自动处理多对象编辑、撤消 和预制件重载,可直接通过编辑器修改 脚本变量,而无需使用 SerializedObject 和 SerializedProperty 系统,如下例所示。
using UnityEditor; using UnityEngine; using System.Collections;
// Example script with properties. public class MyPlayerAlternative : MonoBehaviour { public int damage; public int armor; public GameObject gun;
// ...other code... }
// Custom Editor the "old" way by modifying the script variables directly. // No handling of multi-object editing, undo, and prefab overrides! [CustomEditor (typeof(MyPlayerAlternative))] public class MyPlayerEditorAlternative : Editor {
public override void OnInspectorGUI() { MyPlayerAlternative mp = (MyPlayerAlternative)target;
mp.damage = EditorGUILayout.IntSlider ("Damage", mp.damage, 0, 100); ProgressBar (mp.damage / 100.0f, "Damage");
mp.armor = EditorGUILayout.IntSlider ("Armor", mp.armor, 0, 100); ProgressBar (mp.armor / 100.0f, "Armor");
bool allowSceneObjects = !EditorUtility.IsPersistent (target); mp.gun = (GameObject)EditorGUILayout.ObjectField ("Gun Object", mp.gun, typeof(GameObject), allowSceneObjects); }
// Custom GUILayout progress bar. void ProgressBar (float value, string label) { // Get a rect for the progress bar using the same margins as a textfield: Rect rect = GUILayoutUtility.GetRect (18, 18, "TextField"); EditorGUI.ProgressBar (rect, value, label); EditorGUILayout.Space (); } }
serializedObject | 表示正在检查的一个或多个对象的 SerializedObject。 |
target | 所检查的对象。 |
targets | 正在检查的所有对象的数组。 |
DrawDefaultInspector | 绘制内置检视面板。 |
DrawHeader | 调用此函数以绘制编辑器标头。 |
DrawPreview | 预览绘制的第一个入口点。 |
GetInfoString | 实现此方法以在资源预览上显示资源信息。 |
GetPreviewTitle | 如果要更改 Preview 区域的标签,可重载此方法。 |
HasPreviewGUI | 如果实现 OnPreviewGUI,可在子类中重载此方法。 |
OnInspectorGUI | 实现此函数以创建自定义检视面板。 |
OnInteractivePreviewGUI | 实现此方法可创建您自己的交互式自定义预览。交互式自定义预览用于检视面板和对象选择器的预览区域。 |
OnPreviewGUI | 实现此方法可为检视面板、主编辑器标头和对象选择器的预览区域创建您自己的自定义预览。 |
OnPreviewSettings | 如果要在预览标头中显示自定义控件,可重载此方法。 |
RenderStaticPreview | 如果要渲染静态预览,可重载此方法。 |
Repaint | 重新绘制显示此编辑器的任意检视面板。 |
RequiresConstantRepaint | 是否需要在当前状态下不断重绘此编辑? |
UseDefaultMargins | 如果您不想使用默认边距,可在子类中重载此方法以返回 false。 |
ShouldHideOpenButton | 返回检视面板中“open”按钮的可见性设置。 |
CreateCachedEditor | 返回时,previousEditor 为 targetObject 或 targetObjects 的编辑器。如果该编辑器已在跟踪对象,则函数会返回,否则该函数会销毁之前的编辑器并创建一个新编辑器。 |
CreateCachedEditorWithContext | 使用上下文对象创建缓存的编辑器。 |
CreateEditor | 为 targetObject 或 targetObjects 创建自定义编辑器。 |
CreateEditorWithContext | 使用上下文对象为 targetObject 或 targetObjects 创建自定义编辑器。 |
OnSceneGUI | 启用编辑器以在场景视图中处理事件。 |
finishedDefaultHeaderGUI | 在绘制默认标题项之后,在绘制 Inspector 窗口的标题时引发的事件。 |
GetInstanceID | 返回对象的实例 ID。 |
ToString | 返回 GameObject 的名称。 |
Destroy | 删除 GameObject、组件或资源。 |
DestroyImmediate | 立即销毁对象 /obj/。强烈建议您改用 Destroy。 |
DontDestroyOnLoad | 在加载新的 Scene 时,请勿销毁 Object。 |
FindObjectOfType | 返回第一个类型为 type 的已加载的激活对象。 |
FindObjectsOfType | 返回所有类型为 type 的已加载的激活对象的列表。 |
Instantiate | 克隆 original 对象并返回克隆对象。 |
CreateInstance | 创建脚本化对象的实例。 |
bool | 该对象是否存在? |
operator != | 比较两个对象是否引用不同的对象。 |
operator == | 比较两个对象引用,判断它们是否引用同一个对象。 |