Editor 类

本文深入探讨了如何在Unity中自定义Inspector界面,包括使用SerializedObject与target属性的方法对比,以及支持多选编辑的实现技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继承这个 Editor 类,可以自定义Inspector、Preview、OnSceneGUI

常用于 自定义组件、资源的 Inspector

文档链接 https://docs.unity3d.com/ScriptReference/Editor.html#/

未完待续……………………………..

消息函数

这里写图片描述

属性

这里写图片描述

第一点:
如果不能多个一起编辑,那么会提示 “Multi-object editing not supproted”,所以不用太在意;
如果支持多个一起编辑,那么编辑之后两个物体的值都一样,好像也没什么意思。。。

凭印象来说,最常见的还是用 target(Object类型)

第二点:
几个属性,与 [CanEditMultipleObjects] 属性有较大关系,

[CanEditMultipleObjects] 使用了 SerializedObject 和 SerializedProperty 系统,因此,可以自动处理“多对象编辑”,“撤销undo” 和 “预制覆盖prefab override”。

第三点:两种写法的不同
SerializedObject 是 UnityEditor空间下的,用它来获取属性,用

SerializedProperty  xx = serializedObject.FindProperty("xxx")

//并且特别注意,如果用这种序列化方式,需要在 OnInspectorGUI 开头和结尾各加一句
public override void OnInspectorGUI()
{
    serializedObject.Update();
    //......
    serializedObject.ApplyModifiedProperties();
}

//然而如果用 target属性(Object类型),就不用这个。。。。还是用target稳妥些

target 是 Object 类,UnityEngine空间下的,用强制类型转换就行

MyPlayer mp = (MyPlayer)target;
mp.xxx = EditorGUILayout.XXX(...);

第四点:详细看看Editor类的属性(这些别记了,没事别写多物体编辑不就好了,用 target 属性 妥妥的)

//只能用于 OnInspectorGUI,不能用于 OnSceneGUI、OnPreviewGUI
public SerializedObject serializedObject; 

//如果支持多物体编辑,
//只能用于 OnSceneGUI、OnPreviewGUI,因为target的指向会发生变化
//不能用于 OnInspectorGUI,因为这个target会指向第一个被编辑的物体
//-------------那么如果不支持多物体编辑,那么是不是全都可以用了呢???
public Object target; 

//可用于 OnInspectorGUI,通常用 serializedObject 代替这个 ?
public Object[] targets; 

There are multiple ways to design custom Editors. If you want the Editor to support multi-object editing, you can use the CanEditMultipleObjects attribute. Instead of modifying script variables directly, it’s advantageous to use the SerializedObject and SerializedProperty system to edit them, since this automatically handles multi-object editing, undo, and prefab overrides. If this approach is used a user can select multiple assets in the hierarchy window and change the values for all of them at once.

公有方法(一般用来override)

这里写图片描述

保护方法

protected method

静态方法

这里写图片描述

例子

用 target 属性
//用 target 属性
public class MyPlayerAlternative : MonoBehaviour
{
    public int damage;
    public int armor;
    public GameObject gun;
}

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


    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 属性
public class MyPlayer : MonoBehaviour
{
    public int armor = 75;
    public int damage = 25;
    public GameObject gun;
}

[CustomEditor(typeof(MyPlayer))]
[CanEditMultipleObjects]
public class MyPlayerEditor : Editor
{
    SerializedProperty damageProp;
    SerializedProperty armorProp;
    SerializedProperty gunProp;

    void OnEnable()
    {
        damageProp = serializedObject.FindProperty("damage");  //注意这个 FindProperty
        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();    //最后一行总是加这句
    }

    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();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值