版本: Unity 6 (6000.0)
语言English
  • C#

编辑器

UnityEditor 中的类

/

继承自:ScriptableObject

建议更改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们无法接受所有提交,但我们确实会阅读用户提出的每个建议更改,并在适用的情况下进行更新。

关闭

提交失败

由于某些原因,您的建议更改无法提交。请<a>稍后再试</a>。感谢您抽出时间帮助我们提高 Unity 文档的质量。

关闭

取消

描述

从此基类派生以创建自定义检查器或您自定义对象的编辑器。

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 属性。与其直接修改脚本变量,不如使用 SerializedObjectSerializedProperty 系统来编辑它们,因为这会自动处理多对象编辑、撤消和预制覆盖。如果使用此方法,用户可以在层次结构窗口中选择多个资源,并同时更改所有资源的值。

您可以使用 UIElements 构建自定义 UI,也可以使用 IMGUI。要使用 UIElements 创建自定义检查器,您必须覆盖 Editor.CreateInspectorGUI Editor 类上的方法。要使用 IMGUI 创建自定义检查器,您必须覆盖 Editor.OnInspectorGUI Editor 类上的方法。如果您使用 UIElements 并且已覆盖 Editor.CreateInspectorGUI ,则在同一编辑器上使用 Editor.OnInspectorGUI 的任何现有的 IMGUI 实现都将被忽略。

这是一个自定义检查器的示例


检查器中的自定义编辑器。

using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
[CustomEditor(typeof(MyPlayer))]
public class MyPlayerEditor : Editor
{
    const string resourceFilename = "custom-editor-uie";
    public override VisualElement CreateInspectorGUI()
    {
        VisualElement customInspector = new VisualElement();
        var visualTree = Resources.Load(resourceFilename) as VisualTreeAsset;
        visualTree.CloneTree(customInspector);
        customInspector.styleSheets.Add(Resources.Load($"{resourceFilename}-style") as StyleSheet);
        return customInspector;
    }
}

以下示例定义了 uxml 中自定义检查器的布局。该定义作为资源加载,并且 VisualTreeAsset.CloneTree 方法将层次结构放入 VisualElement 对象中。

InspectorWindow 将实例化一个包含自定义检查器的 InspectorElementInspectorElement 将在自定义检查器上调用 Bind,将其绑定到 MyPlayer 对象。

<UXML xmlns="UnityEngine.UIElements" xmlns:e="UnityEditor.UIElements">
    <VisualElement class="player-property">
        <VisualElement class="slider-row">
            <Label class="player-property-label" text="Damage"/>
            <VisualElement class="input-container">
                <SliderInt class="player-slider" name="damage-slider" high-value="100" direction="Horizontal" binding-path="damage"/>
                <e:IntegerField class="player-int-field" binding-path="damage"/>
            </VisualElement>
        </VisualElement>
        <e:ProgressBar class="player-property-progress-bar" name="damage-progress" binding-path="damage" title="Damage"/>
    </VisualElement>

<VisualElement class="player-property"> <VisualElement class="slider-row"> <Label class="player-property-label" text="Armor"/> <VisualElement class="input-container"> <SliderInt class="player-slider" name="armor-slider" high-value="100" direction="Horizontal" binding-path="armor"/> <e:IntegerField class="player-int-field" binding-path="armor"/> </VisualElement> </VisualElement> <e:ProgressBar class="player-property-progress-bar" name="armor-progress" binding-path="armor" title="Armor"/> </VisualElement>

<e:PropertyField class="gun-field" binding-path="gun" label="Gun Object"/> </UXML>

当数据更改时,UIElements 会自动更新 UI,反之亦然。要绑定数据并自动更新数据和 UI,请设置“绑定路径”属性的值。

检查器的样式在 uss 中完成。

.slider-row {
    flex-direction: row;
    justify-content: space-between;
    margin-top: 4px;
}
.input-container {
    flex-direction: row;
    flex-grow: .6;
    margin-right: 4px;
}
.player-property {
    margin-bottom: 4px;
}
.player-property-label {
    flex:1;
    margin-left: 16;
}
.player-slider {
    flex:3;
    margin-right: 4px;
}
.player-property-progress-bar {
    margin-left: 16px;
    margin-right: 4px;
}
.player-int-field {
    min-width: 48px;
}
.gun-field {
    justify-content: space-between;
    margin-left: 16px;
    margin-right: 4px;
    margin-top: 6px;
    flex-grow: .6;
}

这是一个使用 IMGUI 和多选的自定义检查器的示例

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 (); } }

如果不需要自动处理多对象编辑、撤消和预制覆盖,则编辑器可以直接修改脚本变量,而无需使用 SerializedObjectSerializedProperty 系统,如下面的 IMGUI 示例所示。

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 (); } }

属性

hasUnsavedChanges此属性指定在检查器重建之前,编辑器是否提示用户保存或放弃未保存的更改。
saveChangesMessage如果提示用户保存,则向用户显示的消息。
serializedObject表示正在检查的对象或对象的 SerializedObject。
target正在检查的对象。
targets正在检查的所有对象的数组。

公共方法

CreateInspectorGUI实现此方法以创建自定义 UIElements 检查器。
CreatePreview实现此方法以创建自定义 UIElements 检查器预览。
DiscardChanges放弃对编辑器内容的未保存更改。
DrawDefaultInspector绘制内置检查器。
DrawHeader调用此函数以绘制编辑器的标题。
DrawPreview预览绘制的第一个入口点。
GetInfoString实现此方法以在资源预览的顶部显示资源信息。
GetPreviewTitle如果您想更改预览区域的标签,请覆盖此方法。
HasPreviewGUI如果您实现了 OnPreviewGUI,请在子类中覆盖此方法。
OnInspectorGUI实现此函数以创建自定义检查器。
OnInteractivePreviewGUI实现以创建您自己的交互式自定义预览。交互式自定义预览用于检查器的预览区域和对象选择器。
OnPreviewGUI为检查器的预览区域、主编辑器的标题和对象选择器创建自定义预览。您必须实现 Editor.HasPreviewGUI 才能调用此方法。
OnPreviewSettings如果您想在预览标题中显示自定义控件,请覆盖此方法。
RenderStaticPreview如果您想渲染静态预览,请覆盖此方法。
Repaint重新绘制显示此编辑器的任何检查器。
RequiresConstantRepaint检查此编辑器在其当前状态下是否需要持续重新绘制。
SaveChanges对编辑器的内容执行保存操作。
UseDefaultMargins如果您不希望默认边距,请在子类中覆盖此方法以返回 false。

受保护的方法

ShouldHideOpenButton返回检查器中“打开”按钮的可见性设置。

静态方法

CreateCachedEditor返回时,previousEditor 是 targetObject 或 targetObjects 的编辑器。该函数要么返回编辑器是否已跟踪对象,要么销毁之前的编辑器并创建一个新的编辑器。
CreateCachedEditorWithContext使用上下文对象创建缓存的编辑器。
CreateEditor为 targetObject 或 targetObjects 创建自定义编辑器。
CreateEditorWithContext使用上下文对象为 targetObject 或 targetObjects 创建自定义编辑器。
DrawFoldoutInspector使用带有折叠标题的检查器 GUI 绘制 target。

消息

HasFrameBounds验证是否可以为此编辑器计算自定义边界。
OnGetFrameBounds获取此编辑器目标的自定义边界。
OnSceneGUI使编辑器能够在场景视图中处理事件。

事件

finishedDefaultHeaderGUI在绘制检查器窗口的标题时引发的事件,在绘制默认标题项后。

继承的成员

属性

hideFlags对象是否应隐藏、与场景一起保存或用户可修改?
name对象的名称。

公共方法

GetInstanceID获取对象的实例 ID。
ToString返回对象的名称。

静态方法

Destroy移除游戏对象、组件或资源。
DestroyImmediate立即销毁对象 obj。强烈建议您改用 Destroy。
DontDestroyOnLoad加载新场景时不要销毁目标对象。
FindAnyObjectByType检索类型为 type 的任何活动加载对象。
FindFirstObjectByType检索类型为 type 的第一个活动加载对象。
FindObjectsByType检索类型为 type 的所有加载对象的列表。
Instantiate克隆对象 original 并返回克隆。
InstantiateAsync捕获原始对象(必须与某个游戏对象相关)的快照,并返回 AsyncInstantiateOperation。
CreateInstance创建可脚本化对象的实例。

运算符

bool对象是否存在?
operator !=比较两个对象是否引用不同的对象。
operator ==比较两个对象引用以查看它们是否引用同一对象。

消息

Awake创建 ScriptableObject 实例时调用。
OnDestroy当可脚本化对象将被销毁时调用此函数。
OnDisable当可脚本化对象超出范围时调用此函数。
OnEnable加载对象时调用此函数。
OnValidate仅编辑器函数,当加载脚本或检查器中的值更改时,Unity 会调用此函数。
Reset重置为默认值。