Unity自定义属性抽屉报错:ArgumentException控件位置获取异常
Unity自定义PropertyDrawer报错:ArgumentException:重绘时,在仅含1个控件的组中获取控件1的位置
报错信息
ArgumentException:重绘时,在仅含1个控件的组中获取控件1的位置。
问题代码
[CustomPropertyDrawer (typeof (GameObject))] public class GameObjectDrawer : PropertyDrawer { Editor gameObjectEditor; GameObject _gameObject; public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { GUILayout.Button ("Hello"); } }
我编写了这段自定义PropertyDrawer代码,但不清楚为何会触发上述错误。

问题原因
你在PropertyDrawer的OnGUI方法里混用了基于Rect的固定布局系统和GUILayout自动布局系统。PropertyDrawer的OnGUI方法传入的position参数是Unity指定的固定绘制区域,而GUILayout.Button会自动计算控件位置,两者冲突导致布局计算逻辑混乱,触发这个错误。
另外注意:直接给内置的GameObject类型写自定义PropertyDrawer会覆盖Unity默认的绘制逻辑,容易引发额外问题,建议只针对自定义类或标记了自定义属性的字段做Drawer。
解决方法
方法一:改用基于Rect的固定布局
直接使用传入的position来绘制按钮,符合PropertyDrawer的设计逻辑:
[CustomPropertyDrawer(typeof(GameObject))] public class GameObjectDrawer : PropertyDrawer { Editor gameObjectEditor; GameObject _gameObject; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // 使用GUI.Button,直接传入指定的position区域 if (GUI.Button(position, "Hello")) { // 这里写按钮点击后的逻辑 } } }
方法二:使用自动布局(需重写高度)
如果想保留自动布局,需要重写GetPropertyHeight指定绘制高度,并使用EditorGUI的属性包裹方法,同时用EditorGUILayout而非GUILayout:
[CustomPropertyDrawer(typeof(GameObject))] public class GameObjectDrawer : PropertyDrawer { Editor gameObjectEditor; GameObject _gameObject; // 重写方法告诉Unity这个属性需要的绘制高度 public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { // 返回单行控件的高度,也可以根据需求调整 return EditorGUIUtility.singleLineHeight; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // 必须用BeginProperty和EndProperty包裹,保证属性绘制的正确性 EditorGUI.BeginProperty(position, label, property); // 使用EditorGUILayout.Button,自动布局 if (EditorGUILayout.Button("Hello")) { // 按钮点击逻辑 } EditorGUI.EndProperty(); } }
内容的提问来源于stack exchange,提问作者user17248503
相关产品推荐
相关产品推荐

