gpt4 book ai didi

unity3d - unity 条件字段自定义编辑器

转载 作者:行者123 更新时间:2023-12-05 02:11:17 26 4
gpt4 key购买 nike

我的目标:我有一个脚本

public class MyScript: MonoBehaviour
{
public bool A;
public bool B;
}

只有当 A 为真时,我才需要 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");
}
}
}

但实际上什么都没有改变。我做错了什么?

最佳答案

首先你的类定义是错误的。您要么需要 [Serializable],要么该类应继承自 MonoBehaviour(如果它应附加到 GameObject)。无论哪种方式删除 ()

[Serializable]
public class MyScript
{
public bool A;
public bool B;
}

public class MyScript : MonoBehaviour
{
public bool A;
public bool B;
}

然后注意 Custom Editor 用于从 MonoBehaviourScriptableObject 继承的类。在其他情况下,您宁愿必须实现 Custom PropertyDrawer .

您应该始终尝试直接在target 中进行更改。您将不得不自己处理很多事情,例如标记为脏、撤消/重做等...

而是始终通过 SerializedProperty

另请注意,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 除了你必须使用 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;
}
}

关于unity3d - unity 条件字段自定义编辑器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57759000/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com