自定义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