Unity 编辑器扩展之 Attribute

Unity内置属性详解
本文介绍了Unity内置属性的各种标签,如HideInInspector、Header、Tooltip等,及其使用方法,帮助开发者更好地利用这些特性来增强脚本功能。

Unity内置属性[Attribute]是一种类似修饰功能的标签。可以对OnSceneGUI,InspectorGUI,MenuGUI,WindowGUI等实现各种各样的GUI扩展。用户只要添加上特性标签,就能够自由的使用这些扩展功能。下面列出一些常用的标签:

HideInInspector

隐藏属性在Inspector面板上的显示。在继承了MonoBehaviour的类中,用public修饰的变量如果可以被序列化,那么就会在Inspector中显示,使用HideInInspector可以让他不显示。

using UnityEngine;
public class PuzzleHero : MonoBehaviour
{
    [HideInInspector]
    public string heroName;
}

Header

Header用来给属性添加标题文字。

using UnityEngine;
public class PuzzleHero : MonoBehaviour
{
    [Header("Hero current blood")]
    public float blood;
}

Tooltip

Tooltip用来显示属性标签的提示文字。当鼠标移动到该属性字段上的时候会出现相应的提示。

using UnityEngine;
public class PuzzleHero : MonoBehaviour
{
    [Tooltip("Hero current blood")]
    public float blood;
}

Space

Space,空间占位,可以调整两个属性块之间的间隔距离。可以传参数,表示间距大小,单位是像素。

using UnityEngine;
public class PuzzleHero : MonoBehaviour
{
    public float heart;
    [Space()]
    public float blood;

    [Space(20)]
    public float money;
}

Range

Range使得用户可以使用Slider对类似于int,float,long,double这一类的数值类型进行改变。

using UnityEngine;
public class PuzzleHero : MonoBehaviour
{
    [Range(1, 10)]
    public int num1;

    [Range(1, 10)]
    public float num2;

    [Range(1, 10)]
    public long num3;

    [Range(1, 10)]
    public double num4;
}

Mulitline/TextArea

Textfile默认情况下是只有一行的,但同时也能变成复数行显示的TextArea。Multiline和TextArea功能大致上相同,不过Multiline有着[无法依据宽度自动换行]和[不能使用scroll表示]的限制。

using UnityEngine;
public class PuzzleHero : MonoBehaviour
{
    [Multiline(5)]
    public string multiline;

    [TextArea(3, 5)]
    public string textArea;
}

ColorUsage

颜色拾取器。第一个参数控制是否显示透明通道,第二个参数控制是否使用HDR。

using UnityEngine;
public class PuzzleHero : MonoBehaviour
{
    [ColorUsage(true)]
    public Color color1;

    [ColorUsage(true,true)]
    public Color color2;
}

SerializeField

Unity 默认不会序列化私有变量,如果想强制序列化一个私有变量,那么可以用SerializeField修饰。

using UnityEngine;
public class PuzzleHero : MonoBehaviour
{
    [SerializeField]
    private string str;
}

ExecuteInEditMode

在 Unity 中继承MonoBehaviour的脚本,并不是一直都会执行的。Unity默认只有在Play Mode下,才会运行场景里GameObject下挂载的脚本。如果想在编辑状态下也执行该脚本可以用ExecuteInEditMode修饰,也可以用ExecuteAlways修饰。

using UnityEngine;
[ExecuteInEditMode]
public class PuzzleHero : MonoBehaviour
{
  private void Awake()
  {
    Debug.Log("Excute In Edit Model");
  }
}

HelpURL

在class类上进行帮助文档的链接的设定,设置之后可以点击脚本右上角的问号按钮可以调到对应的网页。

using UnityEngine;
[HelpURL("https://www.xrlmall.top")]
public class PuzzleHero : MonoBehaviour
{

}

AddComponentMenu

可以在UnityEditor的Component的Menu中增加自定义的项目。菜单可以设置多级,使用斜线/分隔即可。在Hierarchy中选中GameObject的时候,点击该菜单项,就可以在GameObject上追加该Component,或者在Inspector面板点击“Add Component”按钮追加。

using UnityEngine;
[AddComponentMenu("Custom/PuzzleHero")]
public class PuzzleHero : MonoBehaviour
{
    
}

ContextMenu

可以在Inspector的ContextMenu中增加选项,执行某个操作。

using UnityEngine;
public class PuzzleHero : MonoBehaviour
{
    [ContextMenu("SaveFile")]
    void DoSomething()
    {
        Debug.Log("save level data to file");
    }
}

DisallowMultipleComponent

对一个MonoBehaviour的子类使用这个属性,那么在同一个GameObject上面,最多只能添加一个该Class的实例。

using UnityEngine;
[DisallowMultipleComponent]
public class PuzzleHero : MonoBehaviour
{
  
}

尝试添加多个的时候,会出现下面的提示。

RequireComponent

在Class上使用,添加对另一个Component的依赖。当该Class被添加到一个GameObject上的时候,如果这个GameObject不含有依赖的Component,会自动添加该Component。且该Componet不可被移除。

using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class PuzzleHero : MonoBehaviour
{
  
}

自动添加Rigidbody,并且不能被移除

MenuItem

快捷键打开资源路径

public class EditorTool
{
	//Alt+R打开资源路径
	[MenuItem("HSJ/快捷方式/打开UI预制路径 &R")]
	static void OpenResourcesUIPanel()
	{
		Selection.activeObject  = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Resources/Prefab/Panel/LoginPanel.prefab");
	}
	//Alt+S打开脚本路径
	[MenuItem("HSJ/快捷方式/打开Panel脚本路径 &S")]
	static void OpenScript()
	{
		Selection.activeObject = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/Scripts/MessageBoxPanel.cs");
	}
	//Alt+S打开指定文件夹路径
	[MenuItem("HSJ/快捷方式/打开工程目录 &O")]
	private static void OpenProjectFolder()
	{
		EditorUtility.RevealInFinder(Application.dataPath);
	}
}

### Unity 编辑器扩展:自定义属性绘制 在 Unity 中,通过扩展编辑器功能可以实现自定义属性的绘制。这通常需要使用 `Editor` 类和相关的 API 来创建自定义检视面板或修改现有组件的显示方式[^1]。 以下是一个完整的教程,展示如何在 Unity 编辑器扩展属性的功能和用法: #### 1. 创建自定义编辑器脚本 为了扩展特定类型的组件,可以使用 `[CustomEditor]` 属性来关联目标组件类与自定义编辑器类。例如,假设有一个名为 `MyCustomComponent` 的组件,可以通过以下代码为其创建一个自定义编辑器: ```csharp using UnityEditor; using UnityEngine; [CustomEditor(typeof(MyCustomComponent))] public class MyCustomComponentEditor : Editor { public override void OnInspectorGUI() { DrawDefaultInspector(); // 绘制默认的属性字段 // 自定义检视面板的内容 if (GUILayout.Button("Perform Custom Action")) { // 执行自定义操作 Debug.Log("Custom action performed!"); } } } ``` 上述代码会在 `MyCustomComponent` 的检视面板中添加一个按钮,点击后会输出日志信息。 #### 2. 使用 `PropertyDrawer` 自定义属性绘制 如果需要为特定属性类型提供自定义绘制逻辑,可以使用 `PropertyDrawer` 类。以下是一个示例,展示如何为带有 `[MyCustomAttribute]` 的字段创建自定义绘制逻辑: ```csharp using UnityEditor; using UnityEngine; // 定义一个自定义属性 public class MyCustomAttribute : PropertyAttribute { } // 创建一个 PropertyDrawer 来处理该属性 [CustomPropertyDrawer(typeof(MyCustomAttribute))] public class MyCustomPropertyDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // 设置标签文本 label = new GUIContent("Custom Label"); // 根据属性类型绘制不同的控件 switch (property.propertyType) { case SerializedPropertyType.Integer: property.intValue = EditorGUI.IntField(position, label, property.intValue); break; case SerializedPropertyType.Float: property.floatValue = EditorGUI.FloatField(position, label, property.floatValue); break; case SerializedPropertyType.String: property.stringValue = EditorGUI.TextField(position, label, property.stringValue); break; default: EditorGUI.PropertyField(position, property, label, true); break; } } } ``` 上述代码会为所有标记了 `[MyCustomAttribute]` 的字段提供自定义绘制逻辑[^3]。 #### 3. 使用 `EditorWindow` 创建独立窗口 虽然问题主要涉及属性扩展,但了解 `EditorWindow` 的使用也有助于理解编辑器扩展的整体机制。以下是一个简单的示例,展示如何创建一个独立的编辑器窗口: ```csharp using UnityEditor; using UnityEngine; public class MyCustomWindow : EditorWindow { [MenuItem("Window/My Custom Window")] public static void ShowWindow() { GetWindow<MyCustomWindow>("My Custom Window"); } private void OnGUI() { GUILayout.Label("This is a custom editor window!", EditorStyles.boldLabel); if (GUILayout.Button("Click Me")) { Debug.Log("Button clicked!"); } } } ``` 此代码会在菜单栏中添加一个选项,用于打开一个包含按钮的自定义窗口[^3]。 #### 4. 使用 `UIBuilder` 和 `VisualElement` 对于更现代的 UI 开发,Unity 提供了 `UIBuilder` 和 `VisualElement`,允许开发者以声明式的方式构建编辑器界面。以下是一个简单的示例: ```csharp using UnityEditor.UIElements; using UnityEngine.UIElements; public class StatusBar : VisualElement { public new class UxmlFactory : UxmlFactory<StatusBar> { } public StatusBar() { var label = new Label("Hello, World!"); Add(label); } } ``` 此代码定义了一个简单的 `StatusBar` 元素,并可通过 UXML 文件实例化[^4]。 --- ### 总结 通过使用 `Editor`、`PropertyDrawer` 和 `EditorWindow` 等类,开发者可以在 Unity 编辑器中实现高度定制化的功能。这些工具不仅限于修改现有组件的显示方式,还可以用于创建全新的编辑器界面。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值