Editor 類

繼承這個 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();
    }
}
發佈了46 篇原創文章 · 獲贊 8 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章