NaughtyAttributes 装饰器属性(Decorator Attributes)完全指南:HorizontalLine 与 InfoBox 的 Inspector 定制实战
游戏开发开发工具【免费下载链接】NaughtyAttributesAttribute Extensions for Unity项目地址https://gitcode.com/gh_mirrors/na/NaughtyAttributes点击查看免费下载本指南深入讲解 NaughtyAttributes 中装饰器属性Decorator Attributes这一核心类别围绕官方文档装饰器属性索引定义的概念模型结合HorizontalLine与InfoBox两个官方属性的源码实现、测试用例与 Inspector 实际效果说明如何在不替换字段原有绘制方式的前提下为字段周围叠加分割线与提示信息框从而提升 Unity Inspector 的可读性与可用性。读完本文你将掌握装饰器属性的定位、两个内置装饰器的全部参数与默认值、它们与 Drawer 属性的组合规则以及其底层 GUI 绘制原理。什么是 Decorator Attributes装饰在字段周围而非替换字段在 NaughtyAttributes 的属性体系中官方文档对 Decorator Attributes 给出了一句精确定义Decorator attributes draw additional GUI around a field, instead of replacing the way the field itself is drawn.即装饰器属性在字段周围绘制额外的 GUI 元素而不是替换字段本身的绘制方式。这与抽屉属性Drawer Attributes形成鲜明对比——Drawer 属性如Dropdown、ProgressBar、MinMaxSlider会接管字段自身的 Inspector 绘制逻辑改变字段的呈现形态而 Decorator 属性只是在字段的上方或周围附加视觉元素分割线、提示框等字段本身依然按照 Unity 默认方式渲染。与 Drawer Attributes 的关键区别官方文档特别用 note 强调了二者在使用规则上的差异见 drawer_attributes/index.rstDrawer 属性一个field、property或function只能挂一个 Drawer 属性Decorator 属性一个field可以同时挂多个Decorator 属性并且可以与一个 Drawer 属性叠加使用。这一规则在源码层面同样成立从属性基类看DrawerAttribute与DecoratorDrawer是两套独立的 Unity 扩展体系。其中 Decorator 属性继承自DrawerAttribute见 DrawerAttribute.cs它本身又是PropertyAttribute与INaughtyAttribute的组合供NaughtyInspectorNaughtyInspector.cs识别并进入自定义绘制流程。官方文档中Decorator Attributes 目录下目前包含两个属性属性作用核心参数HorizontalLine在字段上方绘制一条水平分割线height线高/厚度、color颜色InfoBox在字段上方绘制一个提示信息框text文本、type提示类型下文分别展开。HorizontalLine用一条可定制颜色的水平线分隔 Inspector 字段基本用法与官方示例HorizontalLine的定位与 Unity 自带的Space属性类似——都是用于在 Inspector 中制造视觉间距——但它的表现不是空白而是一条水平线。官方文档horizontal_line.rst给出的示例public class NaughtyComponent : MonoBehaviour { [HorizontalLine(color: EColor.Red)] public int red; [HorizontalLine(color: EColor.Green)] public int green; [HorizontalLine(color: EColor.Blue)] public int blue; }运行后在 Inspector 中即可看到每个字段上方出现一条对应颜色的水平分割线字段本身的int绘制不受影响效果见上文第一张截图。参数说明高度与颜色HorizontalLine共有两个可选参数均带有默认值。其完整定义见源码 HorizontalLineAttribute.cs[AttributeUsage(AttributeTargets.Field, AllowMultiple true, Inherited true)] public class HorizontalLineAttribute : DrawerAttribute { public const float DefaultHeight 2.0f; public const EColor DefaultColor EColor.Gray; public float Height { get; private set; } public EColor Color { get; private set; } public HorizontalLineAttribute(float height DefaultHeight, EColor color DefaultColor) { Height height; Color color; } }参数细节height线的厚度像素默认值2.0f。不传时使用默认值传入更大数值可绘制更粗的分割线例如测试文件中使用的[HorizontalLine(10.0f)]见 HorizontalLineTest.cs。color线的颜色类型为EColor默认值EColor.Gray。注意这里用的是 NaughtyAttributes 自定义的EColor枚举而不是UnityEngine.Color。EColor枚举共定义了 12 种常用颜色定义在 EColor.cs枚举值实际 RGBA 值Color32视觉呈现Clear(0, 0, 0, 0)全透明White(255, 255, 255, 255)白色Black(0, 0, 0, 255)黑色Gray(128, 128, 128, 255)灰色默认Red(255, 0, 63, 255)红色Pink(255, 152, 203, 255)粉色Orange(255, 128, 0, 255)橙色Yellow(255, 211, 0, 255)黄色Green(98, 200, 79, 255)绿色Blue(0, 135, 189, 255)蓝色Indigo(75, 0, 130, 255)靛蓝Violet(128, 0, 255, 255)紫色这些 RGB 值并非 Unity 标准调色板而是项目自定义的视觉配色。枚举通过扩展方法EColorExtensions.GetColor()转换为UnityEngine.Color32同一文件内实现供绘制时使用。源码级剖析HorizontalLine 是如何被绘制出来的HorizontalLine的编辑器端实现位于 HorizontalLineDecoratorDrawer.cs它继承自 Unity 的DecoratorDrawer并通过[CustomPropertyDrawer(typeof(HorizontalLineAttribute))]完成绑定[CustomPropertyDrawer(typeof(HorizontalLineAttribute))] public class HorizontalLineDecoratorDrawer : DecoratorDrawer { public override float GetHeight() { HorizontalLineAttribute lineAttr (HorizontalLineAttribute)attribute; return EditorGUIUtility.singleLineHeight lineAttr.Height; } public override void OnGUI(Rect position) { Rect rect EditorGUI.IndentedRect(position); rect.y EditorGUIUtility.singleLineHeight / 3.0f; HorizontalLineAttribute lineAttr (HorizontalLineAttribute)attribute; NaughtyEditorGUI.HorizontalLine(rect, lineAttr.Height, lineAttr.Color.GetColor()); } }关键实现细节高度计算GetHeight()返回EditorGUIUtility.singleLineHeight lineAttr.Height即在标准单行高度基础上叠加线自身的厚度为分割线及其上下留白预留足够空间缩进对齐OnGUI()先通过EditorGUI.IndentedRect(position)获取与字段缩进对齐的矩形再在垂直方向上偏移singleLineHeight / 3让线与字段顶部保持合理间距实际绘制最终调用NaughtyEditorGUI.HorizontalLine(rect, height, color)。该方法见 NaughtyEditorGUI.cs 中的HorizontalLine方法实现极其轻量——将矩形高度设为线厚然后调用EditorGUI.DrawRect(rect, color)直接填充一个纯色矩形。从实现可以推断HorizontalLine 本质就是一段带缩进的纯色填充矩形因此不支持渐变、圆角等效果。有意思的是NaughtyInspector在绘制 Native Properties、Non-Serialized Fields、Buttons 三类分节标题时内部也复用了NaughtyEditorGUI.HorizontalLine来绘制分节分割线见 NaughtyInspector.cs使用默认的DefaultHeight与DefaultColor。这说明 HorizontalLine 的底层绘制函数是整个 NaughtyAttributes 内部通用的基础能力。实战组合多行分隔 不同颜色 粗线从测试文件 HorizontalLineTest.cs 可以看到官方测试脚本对全部 12 种颜色和自定义厚度的覆盖用法——它将每种颜色配一个[Header]标签进行对照展示同时演示了嵌套可序列化类HorizontalLineNest1、HorizontalLineNest2中装饰器属性同样生效。以下是一个可直接套用的综合示例public class NaughtyComponent : MonoBehaviour { [Header(Black)] [HorizontalLine(color: EColor.Black)] public int black; [Header(Thick)] [HorizontalLine(10.0f)] // 位置参数传入高度10 像素的粗线 public int thick; [HorizontalLine] // 全部使用默认值2.0f 高、Gray 色 public int defaultLine; }InfoBox把 Normal / Warning / Error 提示框直接内嵌进 Inspector基本用法与官方示例InfoBox用于在字段上方提供额外信息提示官方文档info_box.rst给出的示例展示了三种提示类型public class NaughtyComponent : MonoBehaviour { [InfoBox(This is my int, EInfoBoxType.Normal)] public int myInt; [InfoBox(This is my float, EInfoBoxType.Warning)] public float myFloat; [InfoBox(This is my vector, EInfoBoxType.Error)] public Vector3 myVector; }运行效果见上文第二张截图Normal类型显示为蓝色信息框Warning显示为黄色警告框Error显示为红色错误框与 Unity 内置的HelpBox视觉风格一致。参数说明文本与类型InfoBox的定义位于 InfoBoxAttribute.cs。注意EInfoBoxType枚举与该属性类定义在同一个文件中public enum EInfoBoxType { Normal, Warning, Error } [AttributeUsage(AttributeTargets.Field, AllowMultiple true, Inherited true)] public class InfoBoxAttribute : DrawerAttribute { public string Text { get; private set; } public EInfoBoxType Type { get; private set; } public InfoBoxAttribute(string text, EInfoBoxType type EInfoBoxType.Normal) { Text text; Type type; } }参数细节text必填参数即提示框内展示的字符串type可选参数EInfoBoxType枚举默认值Normal。三种类型分别映射到 Unity 的MessageType.Info / Warning / Error。源码级剖析InfoBox 的绘制与高度自适应编辑器端实现位于 InfoBoxDecoratorDrawer.cs[CustomPropertyDrawer(typeof(InfoBoxAttribute))] public class InfoBoxDecoratorDrawer : DecoratorDrawer { public override float GetHeight() { return GetHelpBoxHeight(); } public override void OnGUI(Rect rect) { InfoBoxAttribute infoBoxAttribute (InfoBoxAttribute)attribute; float indentLength NaughtyEditorGUI.GetIndentLength(rect); Rect infoBoxRect new Rect( rect.x indentLength, rect.y, rect.width - indentLength, GetHelpBoxHeight()); DrawInfoBox(infoBoxRect, infoBoxAttribute.Text, infoBoxAttribute.Type); } private float GetHelpBoxHeight() { InfoBoxAttribute infoBoxAttribute (InfoBoxAttribute)attribute; float minHeight EditorGUIUtility.singleLineHeight * 2.0f; float desiredHeight GUI.skin.box.CalcHeight(new GUIContent(infoBoxAttribute.Text), EditorGUIUtility.currentViewWidth); float height Mathf.Max(minHeight, desiredHeight); return height; } private void DrawInfoBox(Rect rect, string infoText, EInfoBoxType infoBoxType) { MessageType messageType MessageType.None; switch (infoBoxType) { case EInfoBoxType.Normal: messageType MessageType.Info; break; case EInfoBoxType.Warning: messageType MessageType.Warning; break; case EInfoBoxType.Error: messageType MessageType.Error; break; } NaughtyEditorGUI.HelpBox(rect, infoText, messageType); } }关键实现细节高度自适应GetHelpBoxHeight()以singleLineHeight * 2.0f为最小高度再通过GUI.skin.box.CalcHeight根据提示文本与当前窗口宽度计算实际需要的文本高度取二者最大值。这意味着提示文本较长时提示框会自动增高换行而不是截断缩进处理OnGUI()利用NaughtyEditorGUI.GetIndentLength(rect)内部通过EditorGUI.IndentedRect计算缩进差值见 NaughtyEditorGUI.cs得到当前层级缩进量使提示框与字段保持同一缩进级别而非贴住 Inspector 左边缘类型映射EInfoBoxType被转换为 Unity 的MessageTypeNormal → InfoWarning → WarningError → Error最终调用NaughtyEditorGUI.HelpBox(rect, infoText, messageType)即EditorGUI.HelpBox与 Unity 原生帮助框渲染完全一致。从实现可以推断InfoBox 本质上就是对 UnityEditorGUI.HelpBox的封装因此它天然支持多行文本换行并具备 Unity 标准帮助框的全部视觉与交互行为。实战组合在嵌套结构中使用三种类型官方测试脚本 InfoBoxTest.cs 演示了在嵌套可序列化类中逐层使用三种类型public class InfoBoxTest : MonoBehaviour { [InfoBox(Normal, EInfoBoxType.Normal)] public int normal; public InfoBoxNest1 nest1; } [System.Serializable] public class InfoBoxNest1 { [InfoBox(Warning, EInfoBoxType.Warning)] public int warning; public InfoBoxNest2 nest2; } [System.Serializable] public class InfoBoxNest2 { [InfoBox(Error, EInfoBoxType.Error)] public int error; }在实际开发中InfoBox 常被用于在复杂字段如曲线、预制体引用、需要特定格式的输入上方说明填写规范与EnableIf/DisableIf等元属性搭配提示当前字段被禁用或隐藏的原因在序列化配置类中标注此参数仅在 XX 模式生效等警告信息。组合用法多个装饰器叠加 与 Drawer 属性共存装饰器属性最独特的价值在于可叠加性。官方文档明确指出一个字段可以同时拥有多个装饰器属性也可以与一个 Drawer 属性组合。这意味着你可以写出这样的字段public class NaughtyComponent : MonoBehaviour { [HorizontalLine(color: EColor.Orange)] [InfoBox(该字段控制角色移动速度仅能在编辑器中调试, EInfoBoxType.Warning)] [ProgressBar(Move Speed, 0f, 100f, EColor.Green)] public float moveSpeed; }在这个例子中HorizontalLine在字段上方绘制橙色分隔线InfoBox提供黄色警告说明ProgressBarDrawer 属性则替换字段本身的绘制将其渲染为进度条。三者职责互不冲突装饰器负责周围Drawer 负责本体叠加后完整呈现装饰 重绘的效果。这正是装饰器属性与 Drawer 属性在设计上刻意区分的结果——前者绝不干预字段自身的绘制。快速上手安装与使用前提本文所有属性均属于 NaughtyAttributes 包体使用前需先安装当前仓库要求Unity 2022.3 或更高版本见 installation.rst。官方提供的三种安装方式通过 openupm-cli 安装推荐openupm add com.dbrizov.naughtyattributes通过 Git URL 安装在项目的Packages/manifest.json中添加com.dbrizov.naughtyattributes: https://github.com/dbrizov/NaughtyAttributes.git#upm从 Asset Store 下载安装包。安装完成后在脚本顶部引入NaughtyAttributes命名空间即可使用[HorizontalLine]、[InfoBox]等全部属性。仓库自带的示例场景位于 Assets/NaughtyAttributes/Samples/DemoScene其中挂载了各属性测试组件的DemoScene.unity可以直接打开查看真实效果对应的测试组件脚本集中在 Assets/NaughtyAttributes/Scripts/Test是学习每个属性参数的最佳参照。小结Decorator Attributes 的定位在字段周围绘制附加 GUI而不替换字段自身绘制因此一个字段可以挂多个装饰器且能与 Drawer 属性共存HorizontalLine本质是带缩进的纯色矩形EditorGUI.DrawRect参数为厚度height默认 2.0f与EColor颜色默认 Gray共 12 种预设色InfoBox本质是对EditorGUI.HelpBox的封装参数为text与EInfoBoxTypeNormal / Warning / Error支持文本换行与缩进对齐高度自动适配内容编辑器实现路径两个属性的绘制逻辑分别位于 HorizontalLineDecoratorDrawer.cs 与 InfoBoxDecoratorDrawer.cs底层复用 NaughtyEditorGUI.cs 的通用绘制方法核心属性定义位于 Core/DrawerAttributes。在序列化字段繁多的 MonoBehaviour 或 ScriptableObject 中善用HorizontalLine分组、用InfoBox标注注意事项可以让团队协作中的 Inspector 界面从字段堆叠变成带注释的分区面板这是 NaughtyAttributes 装饰器属性最直接的工程价值。赞分享游戏开发开发工具【免费下载链接】NaughtyAttributesAttribute Extensions for Unity项目地址https://gitcode.com/gh_mirrors/na/NaughtyAttributes点击查看免费下载相关推荐NaughtyAttributes 元属性Meta Attributes完整指南用 C 特性高效定制 Unity InspectorNaughtyAttributes 元属性Meta Attributes完整指南用 C 特性高效定制 Unity Inspector Meta Attri游戏开发开发工具Midway 3.0 自定义装饰器完全指南类装饰器、属性装饰器、方法装饰器与参数装饰器实战Midway 3.0 自定义装饰器完全指南类装饰器、属性装饰器、方法装饰器与参数装饰器实战 导读 Midway 3.0 提供了一套由框架托管的自定义装饰器能力后端微服务云原生NaughtyAttributes 的 InfoBox 特性详解在 Unity Inspector 中嵌入提示信息框NaughtyAttributes 的 InfoBox 特性详解在 Unity Inspector 中嵌入提示信息框 导读 InfoBox 是 Unity 属游戏开发开发工具上一篇官方 MCP Registry API 全解鉴权令牌交换、服务器过滤同步与状态管理端点实现下一篇解决照片色彩偏差darktable ICC嵌入全流程指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考