1. 程式人生 > >Unity3D Editor 編輯器擴充套件3 Editor指令碼

Unity3D Editor 編輯器擴充套件3 Editor指令碼

Unity3DEditor編輯器擴充套件3 Editor指令碼

環境:Unity2017.2 語言:C#

總起:

在編輯Unity專案的時候,總不可能避免的接觸到Unity自身自帶的Inspector引數調整無法很好的完成某些特定功能的情況。

比方說想要一個按鈕直接能跳到遊戲的主介面進行除錯,然而普通的情況下甚至連新增一個按鈕都做不到。

這邊推薦一下本人花了20幾刀購買的外掛——Odin Inspector & Serializer: http://sirenix.net/odininspector。該外掛能夠摒棄我今天要講的Editor指令碼,非常輕鬆的就能完成一些炫酷的EditorUI。

Odin,我其實研究的不是太深入,因為在實際的專案中並沒有用到,所以該外掛的介紹,我想過段時間深入研究後再說。

今天的主角是Editor指令碼。

Editor指令碼:

♦ 簡單介紹

首先Editor指令碼必須放在Editor資料夾或其子資料夾下,然後我們來看一個Edior指令碼的例子:

//PlayerEditor.cs
[CustomEditor(typeof(Player))]
public class PlayerEditor : Editor
{
    private SerializedProperty hpProperty;

    void Awake()
    {
        Debug.Log("Awake");
    }

    void OnEnable()
    {
        Debug.Log("OnEnable");
        hpProperty = serializedObject.FindProperty("hp");
    }

    public override void OnInspectorGUI()
    {
        // 更新serializedObject,在OnInspectorGUI一開始就要呼叫該函式
        serializedObject.Update();

        // 建立一個Int的滑動條
        EditorGUILayout.IntSlider(hpProperty, 0, 100, new GUIContent("HP"));

        // 使用自定義的滑動條
        ProgressBar(hpProperty.intValue / 100f, "HP");

        // 儲存所有對指令碼修改的值
        serializedObject.ApplyModifiedProperties();
    }

    // 自定義一個滑動條
    void ProgressBar(float value, string label)
    {
        Rect rect = GUILayoutUtility.GetRect(18, 18, "TextField");
        EditorGUI.ProgressBar(rect, value, label);
        EditorGUILayout.Space();
    }

    void OnDisable()
    {
        Debug.Log("OnDisable");
    }

    void OnDestroy()
    {
        Debug.Log("OnDestroy");
    }
}

// Player.cs
public class Player : MonoBehaviour
{
    public int hp;
}

效果如下:

可以注意到,PlayerEditor是繼承於Editor的,除了Awake、OnEnable這類熟悉的生命週期方法外,指令碼中很多操作使用到了UnityEditor.dll裡的內容,而該dll是不會被打包的,所以非Editor資料夾底下的指令碼千萬不要引用到UnityEditor這個名稱空間了。

Editor父類中的serializedObject代表的正是當前操作的這個指令碼,使用以下操作可能更加明瞭:

Player player = (Player)serializedObject.targetObject;

Debug.Log(player.hp);

使用其成員變數targetObject可以直接獲取到對應指令碼進行操作。

具體OnInspectorGUI中的內容,我不想詳細介紹了,主要是使用EditorGUILayout、GUILayout、GUILayoutUtility這三個類。

說到Editor,其實第一篇文章提到的MenuItem最好就是寫在這樣的指令碼中。

♦ Editor指令碼的結構

相比於介紹Editor的使用,我更想深入瞭解一下Editor這個類(使用方面,還有Odin完全可以代替Editor指令碼呢)。

Editor的繼承結構:Editor -> ScriptableObject -> UnityEngine.Object -> object。

Editor除了繼承於ScriptableObject外,還實現了IPreviewable、IToolModeOwner介面。

我們剛剛使用的serializedObject是根據我們寫的Component生成的SerializedObject(注意不是Editor的父類ScriptableObject)物件。

Editor的父類ScriptableObject可能很多人都用過,他可以很方便的儲存一些配置資訊,Prefab、資源引用什麼的。

SerializedObject是UnityEditor名稱空間的,用於以通用的方式操作物件的屬性,可以自動處理撤銷操作,和產生一些預製的樣式UI。

看到這裡,我越來越好奇Unity的物件序列化了,但是這邊反編譯的C#指令碼引用的都是C++內容。

感覺有些遺憾,手頭也沒有C++程式碼,如果有大神指導如何獲取該原始碼,希望能指條明路,謝謝!

個人:

看原始碼的時候,多數都會追到C++的程式碼,看得唯一感覺比較友好的就是UGUI的,因為他基本上都是基於C#來編寫的,雖然內容比較繁雜,但是總也能理清思路。

我手頭上有份Unity4 C++,但感覺不是很全,Transform幾個類倒是有,像SerializedObject便找不到了,可能是我姿勢不對。