lik*_*uku 3 unity-game-engine unity3d-editor unity-editor
我的目标:我有一个脚本
public class MyScript: MonoBehaviour
{
public bool A;
public bool B;
}
Run Code Online (Sandbox Code Playgroud)
仅当 A 为 TRUE 时,我才需要 B 可见
我对脚本进行了扩展,并在标题中添加了 UnityEditor
[CustomEditor(typeof(MyScript))]
public class MyEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
MyScript tool = (MyScript) target;
tool.A = GUILayout.Toggle(tool.A, "Flag");
if(tool.A)
{
tool.B= EditorGUILayout.Toggle(tool.B, "Flag");
}
}
}
Run Code Online (Sandbox Code Playgroud)
但一切都没有真正改变。我做错了什么?
首先你的类定义是错误的。如果该类应附加到游戏对象,则您需要[Serializable]或应该继承该类。MonoBehaviour无论哪种方式删除()
[Serializable]
public class MyScript
{
public bool A;
public bool B;
}
Run Code Online (Sandbox Code Playgroud)
或者
public class MyScript : MonoBehaviour
{
public bool A;
public bool B;
}
Run Code Online (Sandbox Code Playgroud)
然后请注意, a仅Custom Editor适用于从 a或 a继承的类。在其他情况下,您宁愿必须实现Custom。MonoBehaviourScriptableObjectPropertyDrawer
您应该始终尽量不要直接在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();
}
}
Run Code Online (Sandbox Code Playgroud)
或者 ifMyScript实际上不是MonoBehaviourthen as ,PropertyDrawer它的工作原理基本上非常相似,只是您必须使用EditorGUI始终需要位置Rect作为参数的字段的版本:
[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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10827 次 |
| 最近记录: |