继承这个 Editor 类,可以自定义Inspector、Preview、OnSceneGUI
常用于 自定义组件、资源的 Inspector
文档链接 https://docs.unity3d.com/ScriptReference/Editor.html#/
未完待续……………………………..
消息函数
属性
第一点:
如果不能多个一起编辑,那么会提示 “Multi-object editing not supproted”,所以不用太在意;
如果支持多个一起编辑,那么编辑之后两个物体的值都一样,好像也没什么意思。。。
凭印象来说,最常见的还是用 target(Object类型)
第二点:
几个属性,与 [CanEditMultipleObjects] 属性有较大关系,
[CanEditMultipleObjects] 使用了 SerializedObject 和 SerializedProperty 系统,因此,可以自动处理“多对象编辑”,“撤销undo” 和 “预制覆盖prefab override”。
第三点:两种写法的不同
SerializedObject 是 UnityEditor空间下的,用它来获取属性,用
SerializedProperty xx = serializedObject.FindProperty("xxx")
//并且特别注意,如果用这种序列化方式,需要在 OnInspectorGUI 开头和结尾各加一句
public override void OnInspectorGUI()
{
serializedObject.Update();
//......
serializedObject.ApplyModifiedProperties();
}
//然而如果用 target属性(Object类型),就不用这个。。。。还是用target稳妥些
target 是 Object 类,UnityEngine空间下的,用强制类型转换就行
MyPlayer mp = (MyPlayer)target;
mp.xxx = EditorGUILayout.XXX(...);
第四点:详细看看Editor类的属性(这些别记了,没事别写多物体编辑不就好了,用 target 属性 妥妥的)
//只能用于 OnInspectorGUI,不能用于 OnSceneGUI、OnPreviewGUI
public SerializedObject serializedObject;
//如果支持多物体编辑,
//只能用于 OnSceneGUI、OnPreviewGUI,因为target的指向会发生变化
//不能用于 OnInspectorGUI,因为这个target会指向第一个被编辑的物体
//-------------那么如果不支持多物体编辑,那么是不是全都可以用了呢???
public Object target;
//可用于 OnInspectorGUI,通常用 serializedObject 代替这个 ?
public Object[] targets;
There are multiple ways to design custom Editors. If you want the Editor to support multi-object editing, you can use the CanEditMultipleObjects attribute. Instead of modifying script variables directly, it’s advantageous to use the SerializedObject and SerializedProperty system to edit them, since this automatically handles multi-object editing, undo, and prefab overrides. If this approach is used a user can select multiple assets in the hierarchy window and change the values for all of them at once.
公有方法(一般用来override)
保护方法
静态方法
例子
用 target 属性
//用 target 属性
public class MyPlayerAlternative : MonoBehaviour
{
public int damage;
public int armor;
public GameObject gun;
}
// Custom Editor the "old" way by modifying the script variables directly.
// No handling of multi-object editing, undo, and prefab overrides!
[CustomEditor(typeof(MyPlayerAlternative))]
public class MyPlayerEditorAlternative : Editor
{
public override void OnInspectorGUI()
{
MyPlayerAlternative mp = (MyPlayerAlternative)target;
mp.damage = EditorGUILayout.IntSlider("Damage", mp.damage, 0, 100);
ProgressBar(mp.damage / 100.0f, "Damage");
mp.armor = EditorGUILayout.IntSlider("Armor", mp.armor, 0, 100);
ProgressBar(mp.armor / 100.0f, "Armor");
bool allowSceneObjects = !EditorUtility.IsPersistent(target);
mp.gun = (GameObject)EditorGUILayout.ObjectField("Gun Object", mp.gun, typeof(GameObject), allowSceneObjects);
}
void ProgressBar(float value, string label)
{
// Get a rect for the progress bar using the same margins as a textfield:
Rect rect = GUILayoutUtility.GetRect(18, 18, "TextField");
EditorGUI.ProgressBar(rect, value, label);
EditorGUILayout.Space();
}
}
用 serializedObject 属性
//用 serializedObject 属性
public class MyPlayer : MonoBehaviour
{
public int armor = 75;
public int damage = 25;
public GameObject gun;
}
[CustomEditor(typeof(MyPlayer))]
[CanEditMultipleObjects]
public class MyPlayerEditor : Editor
{
SerializedProperty damageProp;
SerializedProperty armorProp;
SerializedProperty gunProp;
void OnEnable()
{
damageProp = serializedObject.FindProperty("damage"); //注意这个 FindProperty
armorProp = serializedObject.FindProperty("armor");
gunProp = serializedObject.FindProperty("gun");
}
public override void OnInspectorGUI()
{
// Update the serializedProperty - always do this in the beginning of OnInspectorGUI.
serializedObject.Update(); // 第一行总是要加这句
// Show the custom GUI controls.
EditorGUILayout.IntSlider(damageProp, 0, 100, new GUIContent("Damage"));
// Only show the damage progress bar if all the objects have the same damage value:
if (!damageProp.hasMultipleDifferentValues)
ProgressBar(damageProp.intValue / 100.0f, "Damage");
EditorGUILayout.IntSlider(armorProp, 0, 100, new GUIContent("Armor"));
// Only show the armor progress bar if all the objects have the same armor value:
if (!armorProp.hasMultipleDifferentValues)
ProgressBar(armorProp.intValue / 100.0f, "Armor");
EditorGUILayout.PropertyField(gunProp, new GUIContent("Gun Object"));
// Apply changes to the serializedProperty - always do this in the end of OnInspectorGUI.
serializedObject.ApplyModifiedProperties(); //最后一行总是加这句
}
void ProgressBar(float value, string label)
{
// Get a rect for the progress bar using the same margins as a textfield:
Rect rect = GUILayoutUtility.GetRect(18, 18, "TextField");
EditorGUI.ProgressBar(rect, value, label);
EditorGUILayout.Space();
}
}