OnInspectorGUI()是Unity的Editor類里的相關(guān)函數(shù),通過(guò)對(duì)該方法的重寫馍迄,可以自定義對(duì)Inspector面板的繪制檀葛。
//Test1.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Test1 : MonoBehaviour
{
public Text Text1;
public bool myBool;
public string myString;
}
//Test1Editor.cs
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Test1))]
public class Test1Editor : Editor
{
public override void OnInspectorGUI()
{
Test1 test = (Test1)target;
test.myBool = EditorGUILayout.Toggle("是否選中", test.myBool);
test.myString = EditorGUILayout.TextField("輸入文本", test.myString);
}
}
這里要先創(chuàng)建Test1腳本,再創(chuàng)建Test1Editor港准,否則引用會(huì)報(bào)錯(cuò)。
如圖對(duì)比咧欣,重寫了OnInspectorGUI之后浅缸,Inspector面板發(fā)生變化。因?yàn)闆](méi)有處理Text1魄咕,重寫之后已經(jīng)無(wú)法設(shè)置衩椒。
以下參考
【Unity 編輯器】擴(kuò)展總結(jié)三:自定義Inspector面板
Unity Editor 基礎(chǔ)篇(二):自定義 Inspector 面板
Unity檢視面板重構(gòu)(OnInspectorGUI重寫)
unity編輯器擴(kuò)展#1 自定義窗口、面板哮兰、和屬性
一毛萌、兩種方式
創(chuàng)建目標(biāo)類,掛載在場(chǎng)景對(duì)象中
using UnityEngine;
public enum Course
{
Chinese,
Mathematics,
English
}
public class InspectorExample : MonoBehaviour
{
public int intValue;
public float floatValue;
public string stringValue;
public bool boolValue;
public Vector3 vector3Value;
public Course enumValue = Course.Chinese;
public Color colorValue = Color.white;
public Texture textureValue;
}
1.繪制方式一
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(InspectorExample))]
public class InspectorExampleEditor : Editor
{
//target指該編輯器類繪制的目標(biāo)類奠蹬,需要將它強(qiáng)轉(zhuǎn)為目標(biāo)類
private InspectorExample _target { get { return target as InspectorExample; } }
//GUI重新繪制
public override void OnInspectorGUI()
{
//EditorGUILayout.LabelField("IntValue",_target.intValue.ToString(),EditorStyles.boldLabel);
//_target.intValue = EditorGUILayout.IntSlider(new GUIContent("Slider"),_target.intValue, 0, 10);
//_target.floatValue = EditorGUILayout.Slider(new GUIContent("FloatValue"), _target.floatValue, 0, 10);
_target.intValue = EditorGUILayout.IntField("IntValue", _target.intValue);
_target.floatValue = EditorGUILayout.FloatField("FloatValue", _target.floatValue);
_target.stringValue = EditorGUILayout.TextField("StringValue", _target.stringValue);
_target.boolValue = EditorGUILayout.Toggle("BoolValue", _target.boolValue);
_target.vector3Value = EditorGUILayout.Vector3Field("Vector3Value", _target.vector3Value);
_target.enumValue = (Course)EditorGUILayout.EnumPopup("EnumValue", (Course)_target.enumValue);
_target.colorValue = EditorGUILayout.ColorField(new GUIContent("ColorValue"), _target.colorValue);
_target.textureValue = (Texture)EditorGUILayout.ObjectField(
"TextureValue", _target.textureValue, typeof(Texture), true);
}
}
2.繪制方式二
using UnityEditor;
[CustomEditor(typeof(InspectorExample))]
public class InspectorExampleEditor : Editor
{
//定義序列化屬性
private SerializedProperty intValue;
private SerializedProperty floatValue;
private SerializedProperty stringValue;
private SerializedProperty boolValue;
private SerializedProperty vector3Value;
private SerializedProperty enumValue;
private SerializedProperty colorValue;
private SerializedProperty textureValue;
private void OnEnable()
{
//通過(guò)名字查找被序列化屬性朝聋。
intValue = serializedObject.FindProperty("intValue");
floatValue = serializedObject.FindProperty("floatValue");
stringValue = serializedObject.FindProperty("stringValue");
boolValue = serializedObject.FindProperty("boolValue");
vector3Value = serializedObject.FindProperty("vector3Value");
enumValue = serializedObject.FindProperty("enumValue");
colorValue = serializedObject.FindProperty("colorValue");
textureValue = serializedObject.FindProperty("textureValue");
}
public override void OnInspectorGUI()
{
//表示更新序列化物體
serializedObject.Update();
EditorGUILayout.PropertyField(intValue);
EditorGUILayout.PropertyField(floatValue);
EditorGUILayout.PropertyField(stringValue);
EditorGUILayout.PropertyField(boolValue);
EditorGUILayout.PropertyField(vector3Value);
EditorGUILayout.PropertyField(enumValue);
EditorGUILayout.PropertyField(colorValue);
EditorGUILayout.PropertyField(textureValue);
//應(yīng)用修改的屬性值,不加的話囤躁,Inspector面板的值修改不了
serializedObject.ApplyModifiedProperties();
}
}
P.S. 第二種繪制方式相較于第一種冀痕,顯示的效果是差不多的。雖然腳本內(nèi)容多了一點(diǎn)狸演,但是方式比較簡(jiǎn)單言蛇。不用根據(jù)每個(gè)變量的數(shù)據(jù)類型選擇相對(duì)應(yīng)的屬性API繪制。
3.使用方式二改造之前的Test1Editor
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Test1))]
public class Test1Editor : Editor
{
//定義序列化屬性
private SerializedProperty Text1;
private SerializedProperty myBool;
private SerializedProperty myString;
private void OnEnable()
{
//通過(guò)名字查找被序列化屬性宵距。
Text1 = serializedObject.FindProperty("Text1");
myBool = serializedObject.FindProperty("myBool");
myString = serializedObject.FindProperty("myString");
Debug.Log("test 1 editor enable");
}
public override void OnInspectorGUI()
{
//Test1 test = (Test1)target;
//test.myBool = EditorGUILayout.Toggle("是否選中", test.myBool);
//test.myString = EditorGUILayout.TextField("輸入文本", test.myString);
//表示更新序列化物體
serializedObject.Update();
EditorGUILayout.PropertyField(Text1);
//EditorGUILayout.PropertyField(myBool);
EditorGUILayout.PropertyField(myBool, new GUIContent("是否選中"));
EditorGUILayout.PropertyField(myString);
//應(yīng)用修改的屬性值腊尚,不加的話,Inspector面板的值修改不了
serializedObject.ApplyModifiedProperties();
}
}
這里PropertyField如果需要修改顯示屬性满哪,可以參考Unity屬性窗口編輯器婿斥,改為EditorGUILayout.PropertyField(myBool, new GUIContent("是否選中"));
4.布局
serializedObject.Update();
EditorGUILayout.BeginHorizontal("box");
EditorGUILayout.PropertyField(Text1);
//EditorGUILayout.PropertyField(myBool);
EditorGUILayout.PropertyField(myBool, new GUIContent("是否選中"));
EditorGUILayout.EndHorizontal();
EditorGUILayout.PropertyField(myString);
水平和垂直布局,注意這是一個(gè)方法對(duì)哨鸭,Begin和End不能少
EditorGUILayout.BeginVertical("box");
//TODO
EditorGUILayout.EndVertical();
EditorGUILayout.BeginHorizontal("box");
//TODO
EditorGUILayout.EndHorizontal();
二民宿、數(shù)組或list集合的顯示方式
參考【Unity 編輯器】擴(kuò)展總結(jié)七:數(shù)組或list集合的顯示方式
using System.Collections.Generic;
using UnityEngine;
public class InspectorExample : MonoBehaviour
{
//序列化
[SerializeField]
public int[] intArray;
[SerializeField]
public List<string> stringList;
}
using UnityEditor;
[CustomEditor(typeof(InspectorExample))]
public class InspectorExampleEditor : Editor
{
private SerializedProperty intArray;
private SerializedProperty stringList;
private void OnEnable()
{
intArray = serializedObject.FindProperty("intArray");
stringList = serializedObject.FindProperty("stringList");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(intArray,true);
EditorGUILayout.PropertyField(stringList, true);
serializedObject.ApplyModifiedProperties();
}
}
三、ReorderableList實(shí)現(xiàn)可排序列表
參考【Unity 編輯器】擴(kuò)展總結(jié)七:數(shù)組或list集合的顯示方式像鸡,原文中還有拓展:ReorderableList添加下拉菜單
活鹰,這里不再轉(zhuǎn)載。
using System.Collections.Generic;
using UnityEngine;
public class TargetExample : MonoBehaviour
{
[SerializeField]
public List<string> stringArray;
}
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
[CustomEditor(typeof(TargetExample))]
public class TargetExampleEditor : Editor
{
private ReorderableList _stringArray;
private void OnEnable()
{
_stringArray = new ReorderableList(serializedObject, serializedObject.FindProperty("stringArray")
, true, true, true, true);
//自定義列表名稱
_stringArray.drawHeaderCallback = (Rect rect) =>
{
GUI.Label(rect, "StringArray");
};
//自定義繪制列表元素
_stringArray.drawElementCallback = (Rect rect,int index,bool selected,bool focused) =>
{
//根據(jù)index獲取對(duì)應(yīng)元素
SerializedProperty item = _stringArray.serializedProperty.GetArrayElementAtIndex(index);
rect.height = EditorGUIUtility.singleLineHeight;
rect.y += 2;
EditorGUI.PropertyField(rect, item, new GUIContent("Element "+index));
};
//當(dāng)添加新元素時(shí)的回調(diào)函數(shù),自定義新元素的值
_stringArray.onAddCallback = (ReorderableList list) =>
{
if (list.serializedProperty != null)
{
list.serializedProperty.arraySize++;
list.index = list.serializedProperty.arraySize - 1;
SerializedProperty item = list.serializedProperty.GetArrayElementAtIndex(list.index);
item.stringValue = "Default Value";
}
else
{
ReorderableList.defaultBehaviours.DoAddButton(list);
}
};
//當(dāng)刪除元素時(shí)候的回調(diào)函數(shù)志群,實(shí)現(xiàn)刪除元素時(shí)着绷,有提示框跳出
_stringArray.onRemoveCallback = (ReorderableList list) =>
{
if (EditorUtility.DisplayDialog("Warnning","Do you want to remove this element?","Remove","Cancel"))
{
ReorderableList.defaultBehaviours.DoRemoveButton(list);
}
};
}
public override void OnInspectorGUI()
{
serializedObject.Update();
//自動(dòng)布局繪制列表
_stringArray.DoLayoutList();
serializedObject.ApplyModifiedProperties();
}
}