Unity 特性 (Attributes)
Unity 中的特性 (Attributes) 是用于在编辑器中控制脚本和变量的显示、行为和功能的注解。Unity 提供了许多内置的特性,用于控制脚本在 Unity 编辑器中的行为,也可以创建自定义特性。特性通常通过方括号 []
包裹,放在字段、方法或类的声明上方。
1. Unity 常用的内置特性
1.1 Inspector 变量可视化相关特性
这些特性主要用于控制 Unity Inspector 面板中脚本变量的显示方式。
特性 | 描述 | 示例 |
---|---|---|
[SerializeField] | 使私有变量在 Inspector 中可见 | [SerializeField] private int score; |
[HideInInspector] | 使公共变量不在 Inspector 中显示 | [HideInInspector] public int hiddenValue; |
[Header(“标题”)] | 在变量上方显示一个标题 | [Header("角色属性")] public float health; |
[Tooltip(“提示信息”)] | 当鼠标悬停在字段上时显示提示 | [Tooltip("这是角色的生命值")] public float health; |
[Range(min, max)] | 在 Inspector 中使用滑块控制数值 | [Range(0, 100)] public float speed; |
[Min(value)] | 限制变量的最小值 | [Min(0)] public int health; |
[Multiline] | 在 Inspector 中为字符串变量提供多行文本框 | [Multiline] public string description; |
[TextArea(minLines, maxLines)] | 定义文本输入的最小和最大行数 | [TextArea(2, 5)] public string notes; |
[Space(value)] | 在变量前插入一个垂直间距 | [Space(10)] public int score; |
1.2 运行时行为相关特性
这些特性用于控制 Unity 脚本的运行时行为。
特性 | 描述 | 示例 |
---|---|---|
[RequireComponent] | 自动为对象添加所需的组件 | [RequireComponent(typeof(Rigidbody))] |
[AddComponentMenu] | 将脚本添加到 “Add Component” 菜单中 | [AddComponentMenu("Custom/MyComponent")] |
[ExecuteInEditMode] | 使脚本在编辑器中也能运行 | [ExecuteInEditMode] |
[ExecuteAlways] | 使脚本在编辑器和运行时都运行 | [ExecuteAlways] |
[DisallowMultipleComponent] | 防止在对象上多次附加此脚本 | [DisallowMultipleComponent] |
[DefaultExecutionOrder(order)] | 指定脚本的执行顺序 | [DefaultExecutionOrder(-100)] |
1.3 编辑器功能扩展特性
这些特性通常用于扩展编辑器的 UI 和自定义行为。
特性 | 描述 | 示例 |
---|---|---|
[CustomEditor] | 自定义编辑器窗口 | [CustomEditor(typeof(MyScript))] |
[MenuItem] | 在 Unity 菜单中添加自定义选项 | [MenuItem("Tools/My Tool")] |
[ContextMenu] | 在 Inspector 变量的右键菜单中添加选项 | [ContextMenu("Reset Values")] |
[ContextMenuItem] | 在字段的右键菜单中添加选项 | [ContextMenuItem("Reset", "ResetValue")] public int score; |
[Gizmo] | 在场景视图中显示自定义图标 | void OnDrawGizmos() { Gizmos.DrawSphere(transform.position, 1); } |
1.4 调试和性能相关特性
这些特性有助于调试、性能分析和错误排查。
特性 | 描述 | 示例 |
---|---|---|
[DebuggerHidden] | 使调试器忽略此方法 | [DebuggerHidden] void HiddenMethod() { } |
[Conditional(“符号名”)] | 仅在定义了特定符号时编译方法 | [Conditional("UNITY_EDITOR")] void DebugMethod() { } |
[ContextMenu] | 在右键菜单中添加功能按钮 | [ContextMenu("Log Message")] void LogMessage() { Debug.Log("Hello!"); } |
2. 特性应用示例
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
[AddComponentMenu("Custom/MyCustomComponent")]
[DisallowMultipleComponent]
public class MyCustomComponent : MonoBehaviour
{
[Header("基本设置")]
[Tooltip("这是角色的移动速度")]
[Range(0, 100)] public float speed = 10;
[Header("高级设置")]
[SerializeField] private float jumpHeight = 5f;
[ContextMenu("重置属性")]
public void ResetValues()
{
speed = 10;
jumpHeight = 5f;
Debug.Log("属性已重置");
}
void Start()
{
Debug.Log("脚本已启动");
}
}
解释:
-
[RequireComponent]:当脚本附加到 GameObject 时,自动为其添加 Rigidbody 组件。
-
[AddComponentMenu]:将脚本显示在 Add Component 菜单的 Custom/MyCustomComponent 路径下。
-
[DisallowMultipleComponent]:防止 GameObject 上出现多个 MyCustomComponent。
-
[Header] 和 [Tooltip]
-
[Range]:将 speed 变量显示为 0 到 100 的滑块。
-
[ContextMenu]:在脚本的 Inspector 面板右键菜单中,提供一个 “重置属性” 的选项。
3. 自定义特性
可以创建自定义特性来满足更复杂的需求。
3.1 自定义特性示例
using UnityEngine;
public class MyCustomAttribute : PropertyAttribute
{
public string message;
public MyCustomAttribute(string message)
{
this.message = message;
}
}
3.2 在脚本中使用自定义特性
using UnityEngine;
public class MyCustomComponent : MonoBehaviour
{
[MyCustom("这是一个自定义的消息")]
public int customValue;
}
3.3 自定义属性绘制器
如果要在 Unity Inspector 中自定义显示方式,需要使用 PropertyDrawer
。
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(MyCustomAttribute))]
public class MyCustomDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
MyCustomAttribute myCustomAttribute = (MyCustomAttribute)attribute;
EditorGUI.LabelField(position, label.text, myCustomAttribute.message);
}
}
解释:
-
CustomPropertyDrawer
:指定自定义属性的绘制器。 -
OnGUI
:自定义如何在 Inspector 中绘制变量。
4. 特性总结
用途 | 常用特性 |
---|---|
变量可视化 | [SerializeField] , [Range] , [Header] , [Tooltip] , [TextArea] |
脚本行为控制 | [RequireComponent] , [AddComponentMenu] , [DisallowMultipleComponent] |
调试和性能 | [ContextMenu] , [Conditional] , [DebuggerHidden] |
自定义 Inspector | [CustomEditor] , [PropertyDrawer] |
5. 常见问题
-
为什么 Inspector 中的私有变量不可见? 需要使用
[SerializeField]
。 -
如何防止在对象上重复附加组件? 使用
[DisallowMultipleComponent]
。 -
如何为变量设置最小值? 使用
[Min(value)]
。