如何让自定义Property Drawer字段与Unity内置字段对齐?
解决UI Toolkit自定义Couple属性Drawer与内置字段对齐问题
我有一个通用Couple类,可像元组一样序列化两个泛型属性。此前用IMGUI实现的自定义Property Drawer能在Inspector中将其放在一行,标签与输入字段均与Unity内置属性对齐。现在迁移到UI Toolkit后功能已基本实现,但无法让字段始终与内置字段对齐。
当前进展
- 查阅Unity文档得知
unity-base-field__aligned类负责拉伸标签宽度以实现对齐,尝试复刻元素树结构并应用该类,但推测它仅对BaseField<T>的子类生效。且该类似乎通过脚本计算宽度并内联应用,我更倾向于使用USS样式和类解决问题。 - 使用
unity-base-field__label类为标签设置最小宽度,在Inspector面板足够小时能达到预期效果,但面板宽度变大后对齐失效。
代码实现
UI Toolkit版本(存在对齐问题)
using UnityEditor; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; [CustomPropertyDrawer(typeof(Couple<,>))] public class CoupleEditor : PropertyDrawer { public override VisualElement CreatePropertyGUI(SerializedProperty property) { // 创建属性容器 var container = new VisualElement(); container.style.flexDirection = FlexDirection.Row; // 创建标签 var label = new Label(property.displayName); label.AddToClassList("unity-base-field__label"); // 设置最小宽度为120px // 创建输入容器 var input = new VisualElement(); input.style.flexDirection = FlexDirection.Row; input.style.flexGrow = 1f; // 创建属性字段 var item1 = new PropertyField(property.FindPropertyRelative(nameof(Couple<int, int>.Item1)), ""); var item2 = new PropertyField(property.FindPropertyRelative(nameof(Couple<int, int>.Item2)), ""); item1.style.flexGrow = 1f; item2.style.flexGrow = 1f; // 添加元素到容器 container.Add(label); input.Add(item1); input.Add(item2); container.Add(input); return container; }
参考:可正常对齐的IMGUI版本
// 可正常工作的IMGUI实现 public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label) { // 对父属性使用BeginProperty/EndProperty,确保预制件覆盖逻辑对整个属性生效 _ = EditorGUI.BeginProperty(rect, label, property); // 绘制标签 rect = EditorGUI.PrefixLabel(rect, GUIUtility.GetControlID(FocusType.Passive), label); // 禁用内联字段的缩进 var indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; // 计算字段矩形 var fieldGap = 8f; var fieldWidth = (rect.width - fieldGap) / 2f; var rect1 = new Rect(rect.x, rect.y, fieldWidth, rect.height); var rect2 = new Rect(rect.x + fieldWidth + fieldGap, rect.y, fieldWidth, rect.height); // 绘制字段 - 传入GUIContent.none让字段不显示自身标签 _ = EditorGUI.PropertyField(rect1, property.FindPropertyRelative(nameof(Couple<int, int>.Item1)), GUIContent.none); _ = EditorGUI.PropertyField(rect2, property.FindPropertyRelative(nameof(Couple<int, int>.Item2)), GUIContent.none); // 恢复缩进 EditorGUI.indentLevel = indent; EditorGUI.EndProperty(); } }
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

