自定义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函數中就可以實現你想要的效果。
上面的代碼中有幾點需要注意:
?。?)[ExecuteInEditMode()]這個函數可以使代碼在編輯模式下運行,不需要運行游戲;
?。?)TestInspectorEditor類必須繼承自Editor,CustomEditor告訴U3D哪個組建類型需要自定義,OnInspectorGUI在顯示組件的Inspector面板時調用;
?。?)SerializedObject序列化物體、SerializedProperty序列化屬性和Editor這三者一起使用,用來訪問和更新組件的屬性,SeriailzedProperty能夠以通用的方式訪問所有的基礎類型,包括對數組的控制等;
?。?)可以在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
總結
以上是生活随笔為你收集整理的自定义Inspector检视面板的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数字广播(数字广播系统设备组成)
- 下一篇: [Altium Designer 学习]