Unity3d 统一条件字段自定义编辑器

Unity3d 统一条件字段自定义编辑器,unity3d,unity3d-editor,unity-editor,Unity3d,Unity3d Editor,Unity Editor,我的目标是: 我有剧本 公共类MyScript:monobhavior { 公共图书馆; 公共图书馆; } 我需要B只有在A为真时才可见 我对脚本进行了扩展,并在标题中添加了UnityEditor [CustomEditor(typeof(MyScript))] 公共类MyEditor:Editor { 公共覆盖无效OnInspectorGUI() { base.OnInspectorGUI(); MyScript工具=(MyScript)目标; tool.A=GUILayout.Toggle

我的目标是: 我有剧本

公共类MyScript:monobhavior
{
公共图书馆;
公共图书馆;
}
我需要B只有在A为真时才可见

我对脚本进行了扩展,并在标题中添加了UnityEditor

[CustomEditor(typeof(MyScript))]
公共类MyEditor:Editor
{
公共覆盖无效OnInspectorGUI()
{
base.OnInspectorGUI();
MyScript工具=(MyScript)目标;
tool.A=GUILayout.Toggle(tool.A,“标志”);
如果(工具A)
{
tool.B=EditorGUILayout.Toggle(tool.B,“标志”);
}
}
}
但一切都没有改变。
我做错了什么?

首先,您的类定义是错误的。您需要
[Serializable]
或者该类应该继承自
monobhavior
,如果它应该附加到游戏对象。无论哪种方式,请删除
()

[可序列化]
公共类MyScript
{
公共图书馆;
公共图书馆;
}

公共类MyScript:monobhavior
{
公共图书馆;
公共图书馆;
}

然后请注意,对于从
monobhavior
ScriptableObject
继承的类,a仅为。在其他情况下,您将不得不实现一个

您应该始终尝试而不是直接在
目标中进行更改。你必须自己处理很多事情,比如标记为脏的、撤销/重做等

而是始终通过
SerializedProperty
s

还要注意
base.OnInspectorGUI()将绘制默认检查器


所以假设
MyScript
是一个
monobhavior

[CustomEditor(typeof(MyScript))]
公共类MyEditor:Editor
{
房地产a;
资产b;
//当相应对象在层次结构中获得焦点时调用一次
私有void OnEnable()
{
//将序列化属性链接到目标的字段
//只做一次更有效
a=序列化对象FindProperty(“a”);
b=序列化对象FindProperty(“b”);
}
公共覆盖无效OnInspectorGUI()
{
//将当前值从实际实例提取到序列化的“克隆”中
serializedObject.Update();
//划出一条直线
EditorGUILayout.PropertyField(a);
if(a.布尔值)
{
//为B绘制字段
EditorGUILayout.PropertyField(b);
}
//将序列化的值写回实际实例
//自动处理所有标记脏和撤消/重做
serializedObject.ApplyModifiedProperties();
}
}

或者,如果
MyScript
实际上不是
monobhavior
,那么as
PropertyDrawer
的工作原理基本上非常相似,只是您必须使用
EditorGUI
版本的字段,这些字段总是需要一个position
Rect
作为参数:

[CustomPropertyDrawer(typeof(MyScript),true)]
公共类MyEditor:PropertyDrawer
{
私有布尔展开;
public override void OnGUI(Rect位置、SerializedProperty属性、GUIContent标签)
{
//为整个类绘制文件夹
isUnFolded=EditorGUI.Foldout(新的矩形(position.x、position.y、position.width、EditorGUIUtility.singleLineHeight)、isUnFolded、label);
//转到下一行
position.y+=EditorGUIUtility.singleLineHeight;
//仅在展开时绘制其余部分
如果(未展开)
{
//绘制缩进的字段
EditorGUI.indentLevel++;
//与之前类似,获取字段的相应序列化属性
var a=属性。FindPropertyRelative(“a”);
var b=property.FindPropertyRelative(“b”);
//划界
EditorGUI.PropertyField(新的Rect(position.x,position.y,position.width,EditorGUIUtility.singleLineHeight),a);
position.y+=EditorGUIUtility.singleLineHeight;
if(a.布尔值)
{
//画B场
EditorGUI.PropertyField(新的Rect(position.x,position.y,position.width,EditorGUIUtility.singleLineHeight),b);
}
//复位压痕
EditorGUI.indentLevel--;
}
}
//重要的是,您必须实现这一点,因为您的新属性是
//高于1条单行线
公共覆盖浮点GetPropertyHeight(SerializedProperty属性,GUIContent标签)
{
//默认值为1行
var高度=1;
//如果展开至少多1行,如果a为真,则多2行
如果(未展开)高度+=(property.FindPropertyRelative(“A”).boolValue?2:1);
返回高度*EditorGUIUtility.singleLineHeight;
}
}

有些错误是可以犯的。首先,我应该把它写成MonoBehavior(更新了问题),因为这就是我的类(打字错误),但是你不会把你的答案扩展到PropertyDrawer。因此,我现在要两次感谢你