Related Posts Plugin for WordPress, Blogger...

2-11 Writing Custom Editors

大家是否有發現新版的CameraRaycaster有神奇的功能呢?在Inspector視窗中,會看見如下圖一樣有下拉式選單可以選擇不同的Layer,明明在程式碼中他就只是一個int型別的陣列呀!

這是因為Unity可以自製編輯器,有興趣學習Editor的人,可以看官網的教學手冊,或是自行上網找更多的教學文章。
https://docs.unity3d.com/Manual/AdvancedEditor.html

大家可以開啟先前匯入到Editor/CameraRaycasterEditor.cs檔案看看,以下都替大家寫好註解了!


using UnityEditor;


// TODO consider changing to a property drawer
[CustomEditor(typeof(CameraRaycaster))]
public class CameraRaycasterEditor : Editor
{
    bool isLayerPrioritiesUnfolded = true; // store the UI state

    public override void OnInspectorGUI()
    {
        // serializedObject物件繼承自Editor,呼叫Update更新CameraRaycaster實體
        serializedObject.Update(); 
        // 產生Foldout功能,長得像下拉式抽屜可以開合的功能
        isLayerPrioritiesUnfolded = EditorGUILayout.Foldout(isLayerPrioritiesUnfolded, "Layer Priorities");
        if (isLayerPrioritiesUnfolded)
        {
               // 字段標籤的縮進級別,級別增加後新增的組件都會往後縮
            EditorGUI.indentLevel++;
            {
                BindArraySize();
                BindArrayElements();
            }
               // 上述組件新增完後再將縮進級別調整回來
            EditorGUI.indentLevel--;
        }

        // 將Inspector的任何變更寫入到變數中
        serializedObject.ApplyModifiedProperties();
    }

    void BindArraySize()
    {
        // 取得layerPriorities變數的值
        int currentArraySize = serializedObject.FindProperty("layerPriorities.Array.size").intValue;
        // 產生整數欄位,標籤名稱為Size,並會實時回傳該欄位任何的變化
        int requiredArraySize = EditorGUILayout.IntField("Size", currentArraySize);
        // 若欄位有變化,則將新增值更新到layerPriorities變數
        if (requiredArraySize != currentArraySize)
        {
            serializedObject.FindProperty("layerPriorities.Array.size").intValue = requiredArraySize;
        }
    }

    void BindArrayElements()
    {
        int currentArraySize = serializedObject.FindProperty("layerPriorities.Array.size").intValue;
        for (int i = 0; i < currentArraySize; i++)
        {
               // 取得Array的值,並產生下拉式選單
            var prop = serializedObject.FindProperty(string.Format("layerPriorities.Array.data[{0}]", i));
            prop.intValue = EditorGUILayout.LayerField(string.Format("Layer {0}:", i), prop.intValue);
        }
    }

}

留言