首先你的类定义是错误的。您要么需要[Serializable],要么该类应从MonoBehaviour 继承,如果它应附加到游戏对象。无论哪种方式删除()
[Serializable]
public class MyScript
{
public bool A;
public bool B;
}
或
public class MyScript : MonoBehaviour
{
public bool A;
public bool B;
}
然后请注意,Custom Editor仅适用于继承自 MonoBehaviour 或 ScriptableObject 的类。在其他情况下,您将不得不实现Custom PropertyDrawer。
您应该始终尝试不直接在target 中进行更改。您必须自己处理很多事情,例如标记为脏、撤消/重做等...
而总是通过SerializedPropertys。
还要注意base.OnInspectorGUI(); 将绘制默认检查器
所以假设 MyScript 是一个 MonoBehaviour 类
[CustomEditor(typeof(MyScript))]
public class MyEditor : Editor
{
SerializedProperty a;
SerializedProperty b;
// is called once when according object gains focus in the hierachy
private void OnEnable()
{
// link serialized properties to the target's fields
// more efficient doing this only once
a = serializedObject.FindProperty("A");
b = serializedObject.FindProperty("B");
}
public override void OnInspectorGUI()
{
// fetch current values from the real instance into the serialized "clone"
serializedObject.Update();
// Draw field for A
EditorGUILayout.PropertyField(a);
if(a.boolValue)
{
// Draw field for B
EditorGUILayout.PropertyField(b);
}
// write back serialized values to the real instance
// automatically handles all marking dirty and undo/redo
serializedObject.ApplyModifiedProperties();
}
}
或者如果MyScript实际上不是MonoBehaviour,那么PropertyDrawer的工作原理基本上非常相似,除了你必须使用总是需要位置Rect作为参数的字段的EditorGUI版本:
[CustomPropertyDrawer(typeof(MyScript), true)]
public class MyEditor : PropertyDrawer
{
private bool isUnFolded;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// draw folder for the entire class
isUnFolded = EditorGUI.Foldout(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), isUnFolded, label);
// go to the next line
position.y += EditorGUIUtility.singleLineHeight;
// only draw the rest if unfolded
if (isUnFolded)
{
// draw fields indented
EditorGUI.indentLevel++;
// similar to before get the according serialized properties for the fields
var a = property.FindPropertyRelative("A");
var b = property.FindPropertyRelative("B");
// Draw A field
EditorGUI.PropertyField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), a);
position.y += EditorGUIUtility.singleLineHeight;
if (a.boolValue)
{
// Draw B field
EditorGUI.PropertyField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), b);
}
// reset indentation
EditorGUI.indentLevel--;
}
}
// IMPORTANT you have to implement this since your new property is
// higher then 1 single line
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
// default is 1 single line
var height = 1;
// if unfolded at least 1 line more, if a is true 2 lines more
if(isUnFolded) height += (property.FindPropertyRelative("A").boolValue ? 2 : 1);
return height * EditorGUIUtility.singleLineHeight;
}
}