自定義Inspector檢視面板


Unity中的Inspector面板可以顯示的屬性包括以下兩類:
(1)C#以及Unity提供的基礎類型;
(2)自定義類型,並使用[System.Serializable]關鍵字序列化,比如:
[System.Serializable]
public class TestClass { public Vector3 vec = Vector3.zero; public Color clr = Color.green; }

  也可以使用[System.NonSerialized]標記不需要顯示的屬性,比如:

public class TestClass
{
    [System.NonSerialized]
    public Vector3 vec = Vector3.zero; }

  有的時候對於U3D默認的Inspector不能滿足需求,則可以對特定類型的Inspector面板進行自定義:編寫一個對應的Editor類,然后重寫其OnInspector方法,比如我們有如下類型:

using UnityEngine;
using System.Collections; [System.Serializable] public class TestClass { public Vector3 vec = Vector3.zero; [System.NonSerialized] public Color clr = Color.green; } [ExecuteInEditMode()] [RequireComponent(typeof(TestComponent))] public class TestInspector : MonoBehaviour { public Vector3 lookAtPoint = Vector3.zero; public Vector3 pos = Vector3.zero; public TestClass testObj = new TestClass(); void Update() { transform.LookAt(lookAtPoint); transform.position = pos; } }

  然后在Editor目錄下添加如下腳本:

using UnityEngine;
using UnityEditor; using System.Collections; [CustomEditor(typeof(TestInspector))] public class TestInspectorEditor : Editor { private SerializedObject obj; private SerializedProperty lookAtPoint; private SerializedProperty pos; private SerializedProperty testObj; // 添加TestInspector組件的GameObject被選中時觸發該函數 void OnEnable() { obj = new SerializedObject(target); lookAtPoint = obj.FindProperty("lookAtPoint"); pos = obj.FindProperty("pos"); testObj = obj.FindProperty("testObj"); } // 重寫Inspector檢視面板 public override void OnInspectorGUI() { obj.Update(); EditorGUILayout.PropertyField(lookAtPoint); EditorGUILayout.PropertyField(pos); EditorGUILayout.PropertyField(testObj, true); // 第二個參數表示有子節點需要顯示  obj.ApplyModifiedProperties(); } }

  在OnInspector函數中就可以實現你想要的效果。

   上面的代碼中有幾點需要注意:

  (1)[ExecuteInEditMode()]這個函數可以使代碼在編輯模式下運行,不需要運行游戲;

  (2)TestInspectorEditor類必須繼承自Editor,CustomEditor告訴U3D哪個組建類型需要自定義,OnInspectorGUI在顯示組件的Inspector面板時調用;

  (3)SerializedObject序列化物體、SerializedProperty序列化屬性和Editor這三者一起使用,用來訪問和更新組件的屬性,SeriailzedProperty能夠以通用的方式訪問所有的基礎類型,包括對數組的控制等;

   (4)可以在OnInspectorGUI中調用DrawDefaultInspector函數用來顯示默認的監事面板內容;

   (5)EditorGUILayout.PropertyField(testObj, true);如果該類型有子節點,第二個參數需要設置為true才能正確的展開;

   (6)[HideInInspector]也可用於隱藏屬性顯示。

******************************************************************************************

  除了自定義Inspector檢視面板,我們還可以類似的方法自定義場景視圖中對物體的控制,方法是重定義Editor的OnSceneGUI()函數,比如:

using UnityEngine;
using UnityEditor;
using System.Collections;

[CustomEditor(typeof(TestInspector))]
public class TestInspectorEditor : Editor
{

    private SerializedObject obj;
    private SerializedProperty lookAtPoint;
    private SerializedProperty pos;
    private SerializedProperty testObj;

    // 添加TestInspector組件的GameObject被選中時觸發該函數
    void OnEnable()
    {
        obj = new SerializedObject(target);
        lookAtPoint = obj.FindProperty("lookAtPoint");
        pos = obj.FindProperty("pos");
        testObj = obj.FindProperty("testObj");
    }

    // 重寫Inspector檢視面板
    public override void OnInspectorGUI()
    {
        obj.Update();

        EditorGUILayout.PropertyField(lookAtPoint);
        EditorGUILayout.PropertyField(pos);
        EditorGUILayout.PropertyField(testObj, true);   // 第二個參數表示有子節點需要顯示

        obj.ApplyModifiedProperties();
    }

    void OnSceneGUI()
    {
        // 繪制一條由target到世界坐標原點的直線,顏色為黃色
        Handles.color = Color.yellow;
        Handles.DrawLine((target as TestInspector).transform.position, Vector3.zero);
        // 創建一個位置控制柄
        Handles.PositionHandle(Vector3.zero, Quaternion.identity);
        // 創建一個滑動控制柄,可以沿某個方向滑動target
        Handles.Slider((target as TestInspector).transform.position, Vector3.zero);

        (target as TestInspector).transform.position = Handles.FreeMoveHandle((target as TestInspector).transform.position, Quaternion.identity, 2.0f, Vector3.zero, Handles.DrawRectangle);
       
        if (GUI.changed)
        {
            EditorUtility.SetDirty(target);
        }
    }

}

  主要是使用Handles編輯器類來進行自定義,該類型提供了很多方便的操作接口,比如DrawLine、DrawCube、DrawBezier等。

  注意,不能在OnSceneGUI中使用SerializedObject。

  這篇帖子寫得很不錯:http://blog.csdn.net/lilanfei/article/details/7680802


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM