Unity Attribute标签用法

Unity Attribute标签用法

标记字段

[ColorUsage(false, true, 0f, 8f, 1f, 1f)]

第一个参数:是否启用 Alpha 通道
第二个参数:是否启用 HDR 模式,启用后多四个参数为 最小/最大亮度,最小/最大曝光度

using UnityEngine;
public class Example : MonoBehaviour
{
    [ColorUsage(false, true)] 
    public Color hdrColorWithoutAlpha = Color.white;
}

[ContextMenuItem(“显示的方法名”,“方法”)]

标记字段,在Inspector面板上给字段添加一个右键菜单,并执行指定的函数

using UnityEngine;
public class Example : MonoBehaviour
{
    [ContextMenuItem("Reset", "ResetBiography")]
    [Multiline(8)]
    string playerBiography = "";    
    void ResetBiography()
    {
        playerBiography = "";
    }
}

[Delayed]

当使用此属性时,对于int、float、string类型的变量,在Inspector面板修改变量值时,只有按下Enter键 或 鼠标失去焦点后才会返回新数值

public class DelayedExample : MonoBehaviour {

    // Attribute used to make a float, int, or string variable in a script be delayed.
    // When this attribute is used, the float, int, or text field will not return a new value
    // until the user has pressed enter or focus is moved away from the field.

    [Delayed]
    public int intValue = 22;
    [Delayed]
    public float floatValue = 0.618f;
    [Delayed]
    public string stringValue = "test delayed attribute";

}

[FormerlySerializedAs(“XXX”)]

可以让变量以其他名称进行序列化,并且在变量自身修改名称的时候,不会丢失之前的序列化的值

using UnityEngine;
using UnityEngine.Serialization;
public class MyMonster : MonoBehaviour
{
    [FormerlySerializedAs("hitpoints")]
    public int health;
}

[GradientUsage]

在 Gradient 类型的变量使用此属性,可以设置是否为 HDR 渐变模式

public class GradientUsageExample : MonoBehaviour {

    // Attribute used to configure the usage of the GradientField and Gradient Editor for a gradient.

    // Use this attribute on a Gradient to configure the GradientField and Gradient Editor to treat the colors as HDR colors or as normal LDR colors.

    [GradientUsage(true)]
    public Gradient gradient;

}

[Header(“XXX”)]

通过Header在字段上放添加描述,会在Inspector面板上显示,可以将属性隔离开,形成分组的感觉

using UnityEngine;
public class Example : MonoBehaviour
{
    [Header("Health Settings")]
    public int health = 0;
    public int maxHealth = 100;    
    [Header("Shield Settings")]
    public int shield = 0;
    public int maxShield = 0;
}
// 可以通过.header属性获取标签中配置的文本

[HideInInspector]

使属性在Inspector中隐藏,仍可序列化,赋值可以通过写程序进行赋值

using UnityEngine;
public class Example : MonoBehaviour
{
    // Make the variable p not show up in the inspector
    // but be serialized.
    [HideInInspector]
    int p = 5;
}

[Min(min)]

限制一个 float,int 类型的变量的最小值

using UnityEngine;
public class Example : MonoBehaviour
{
    // Set a specific minimum value.
    [Min(0)] 
    public float radius = 5;
}

[Multiline]

添加在string类型的变量上,可以在Inspector面板上显示一个多行文本框

public class MultilineExample : MonoBehaviour {

    [Multiline(8)] 
    // Attribute to make a string be edited with a multi-line textfield.
    public string value;

}

[Range(min, max)]

限制数值变量的取值范围,并以滑动条在Inspector面板中显示

using UnityEngine;

public class Example : MonoBehaviour
{
    // This integer will be shown as a slider,
    // with the range of 1 to 6 in the Inspector
    [Range(1, 6)]
    public int integerRange;

    // This float will be shown as a slider,
    // with the range of 0.2f to 0.8f in the Inspector
    [Range(0.2f, 0.8f)]
    public float floatRange;
}

[SerializeField]

强制序列化一个私有的变量,使其可以在Inspector面板显示,很多UI都会对private的组件进行强制序列化

using UnityEngine;

public class SomePerson : MonoBehaviour
{
    //This field gets serialized because it is public.
    public string firstName = "John";    
    //This field does not get serialized because it is private.
    private int age = 40;    
    //This field gets serialized even though it is private
    //because it has the SerializeField attribute applied.
    [SerializeField]
    private bool hasHealthPotion = true;    
    void Start()
    {
        if (hasHealthPotion)
            Debug.Log("Person's first name: " + firstName + " Person's age: " + age);
    }
}

[Space]

可以与上一个属性拉开指定的空隙

using UnityEngine;

public class Example : MonoBehaviour
{
    int health = 0;
    int maxHealth = 100;

    // 10 pixels of spacing here.
    [Space(10)] 

    int shield = 0;
    int maxShield = 0;
}

[TextArea]

该属性可以把string在Inspector面板上变为一个带有滚动条的文本域

using UnityEngine;

public class TextAreaExample : MonoBehaviour
{
    [TextArea]
    public string MyTextArea;
}

[Tooltip(“XXX”)]

当变量添加这个属性后,在Inspector面板将鼠标悬停在该变量上可以看到提示

cusing UnityEngine;
public class Example : MonoBehaviour
{
    [Tooltip("Health value between 0 and 100.")]
    int health = 0;
}

[NonSerialized]

在Inspector面板中隐藏public属性,不执行序列化

using UnityEngine;
public class Example : MonoBehaviour
{
    // p will not be shown in the inspector or serialized
    [System.NonSerialized]
    public int p = 5;
}

[System.Serializable]

使自定义的类能进行序列化,即当做一个public成员的时候可以在Inspector显示

using System;
using UnityEngine;

public class Player : MonoBehaviour
{
    //Create a custom struct and apply [Serializable] attribute to it
    [Serializable]
    public struct PlayerStats
    {
        public int movementSpeed;
        public int hitPoints;
        public bool hasHealthPotion;
    }

    //Make the private field of our PlayerStats struct visible in the Inspector
    //by applying [SerializeField] attribute to it
    [SerializeField]
    private PlayerStats stats;
}

[InspectorName(“xxx”)]

通过此属性可以改变枚举值在Inspector面板上显示的名字

using UnityEngine;
public enum ModelImporterIndexFormat
{
    Auto = 0,
    [InspectorName("16 bits")]
    UInt16 = 1,
    [InspectorName("32 bits")]
    UInt32 = 2,
}

自定义标签

Header源代码

using System;

namespace UnityEngine
{
  /// <summary>
  ///   <para>Use this PropertyAttribute to add a header above some fields in the Inspector.</para>
  /// </summary>
  [AttributeUsage(AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
  public class HeaderAttribute : PropertyAttribute
  {
    /// <summary>
    ///   <para>The header text.</para>
    /// </summary>
    public readonly string header;

    /// <summary>
    ///   <para>Add a header above some fields in the Inspector.</para>
    /// </summary>
    /// <param name="header">The header text.</param>
    public HeaderAttribute(string header) => this.header = header;
  }
}

自定义标签

// 成对事件标签
// 使用:[Pairs(End_Event_Name)] End_Event_Name填写对应的结束事件名称
public class PairsAttribute : Attribute
{
    // EventType枚举事件,此处用于记录结束事件
    public readonly EventType pairs;
    public PairsAttribute(EventType pairs)
    {
        this.pairs = pairs;
    }
}

标记类/方法

[AddComponentMenu(“XXX/XX/XXX”)]

让Component菜单下出现你自定义的类,位置是“XXX/XX/XXX”

using UnityEngine;
[AddComponentMenu("Transform/Follow Transform")]
public class FollowTransform : MonoBehaviour
{
}

[AssemblyIsEditorAssembly]

汇编级属性,使用该属性的任何类会被认为是编辑器类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// Assembly level attribute. Any classes in an assembly with this attribute will be considered to be Editor Classes.

// 这个程序集下的任何类都会被引擎认为是编辑器类,
// 例如:在这个程序集里,继承MonoBehaviour的脚本都不能被挂载到GameObject上
// Add 'AssemblyIsEditorAssembly' attribute to this assembly.
[assembly: AssemblyIsEditorAssembly] 
namespace UnityAttributesExample {

    public class AssemblyIsEditorAssemblyExample : MonoBehaviour {

    }
}

[ContextMenu(“xxx”)]

[MenuItem(“CONTEXT/组建名/菜单名”)]

标记函数:在Inspector面板,右击包含这条标记的脚本,出现“xxx”的菜单选项。
注:对应的函数不能是static
标记的函数可以添加 MenuCommand cmd 参数,cmd.context转换为当前组建类型后操作

using UnityEngine;public class ContextTesting : MonoBehaviour
{
    /// Add a context menu named "Do Something" in the inspector
    /// of the attached script.
    [ContextMenu("Do Something")]
    void DoSomething()
    {
        Debug.Log("Perform operation");
    }
}

[CreateAssetMenu(menuName = "MySubMenue/Create XXX ")]

标记类,可以给project面板下的Creat 菜单下新建一个自定义子菜单,用于新建自定义资源

[CreateAssetMenu(fileName = "xxxSetting", menuName = "xxxSetting")]
public class xxxSetting : ScriptableObject
{
    public List<string> names;
    void DoSomething()
    {
        Debug.Log("Perform operation");
    }
}

[RequireComponent(typeof(ClassName))]

使用该属性的脚本被添加到GameObject上时,会自动添加ClassName这个类,能够有效避免在设置出错。

using UnityEngine;

// PlayerScript requires the GameObject to have a Rigidbody component
[RequireComponent(typeof(Rigidbody))]
public class PlayerScript : MonoBehaviour
{
    Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        rb.AddForce(Vector3.up);
    }
}

[ExecuteAlways]

脚本添加此属性后,无论是在 Edit Mode 还是 Play Mode 都会执行

using UnityEngine;

[ExecuteAlways]
public class ExampleClass : MonoBehaviour
{
    void Start()
    {
        if (Application.IsPlaying(gameObject))
        {
            // Play logic
        }
        else
        {
            // Editor logic
        }
    }
}

[ExecuteInEditMode]

脚本添加此属性后,可以在Edit Mode编辑模式下执行。

// The PrintAwake script is placed on a GameObject.  The Awake function is usually
// called when the GameObject is started at runtime.  Due to the ExecuteInEditMode
// attribute, the script is also called by the Editor.  The Awake() function will be called,
// for example, when the Scene is changed to a
// different Scene in the Project window.
// The Update() function is called, for example, when the GameObject transform
// position is changed in the Editor.

using UnityEngine;

[ExecuteInEditMode]
public class PrintAwake : MonoBehaviour
{
    void Awake()
    {
        Debug.Log("Editor causes this Awake");
    }

    void Update()
    {
        Debug.Log("Editor causes this Update");
    }
}

[CustomEditor(typeof(ClassName))]

声明一个Class为自定义Editor的Class,可以制作一个自定义编辑器
[MenuItem(“一级菜单名/二级菜单名 _全局快捷键”]
  标记函数:在菜单中出现选项栏,执行对应功能。注:对应的函数必须是static
  [MenuItem(“一级菜单名/二级菜单名”,false,1)]
  第三个参数决定菜单的优先级。间隔超过10,就另开一组,用下划线分隔
  第二个参数是true则是是给该菜单项添加验证,分别标记两个函数,true标记的函数作为false 标记的函数能否启用并执行的验证,菜单名,优先级要相同
  GameObject菜单与Hierarchy面板右键菜单一样,优先级在10左右。
  Assets菜单与project面板右键菜单一样
  菜单名 + _快捷键,给菜单指定单一快捷键
  菜单名 + %快捷键,给菜单指定组合快捷键 %-Ctrl #-Shift &-Alt

[PreferBinarySerialization]

只能用于 ScriptableObject 的派生类,使用二进制进行序列化。这个属性可以提升大量数据资源文件的读写性能。可以搭配 CreateAssetMenu 属性一起使用

[SerializeReference]

序列化时共享相同的对象数据,可以用来减少序列化的内容

[GUITarget(0)]

标记OnGUI()函数,控制对应的 OnGUI 在哪个 Display 显示

[HelpURL(“http://www.baidu.com”)]

标记一个类提供一个帮助文档的URL,点击后可以跳转到该网址(与自带组件点击小树效果相同)

[DisallowMultipleComponent]

对一个MonoBehaviour的子类使用这个属性,那么在同一个GameObject上面,最多只能添加一个该Class的实例。尝试添加多个的时候,会出现Can't add script提示。

[ImageEffectOpaque]

在OnRenderImage上使用,可以让渲染顺序在非透明物体之后,透明物体之前

using UnityEngine;
public class ExampleClass : MonoBehaviour
{
    void Start()
    {
       
    }
    [ImageEffectOpaque]
    void OnRenderImage (RenderTexture source, RenderTexture destination)
    {
        
    }
}

[ImageEffectTransformsToLDR]

渲染从从HDR变为LDR 具体使用方法不明

[RuntimeInitializeOnLoadMethod(loadType)]

此属性仅在Unity5上可用。在游戏启动时(runtime),会自动调用添加了该属性的方法(Awake之后)。要注意的是使用这个属性的方法的调用顺序是不确定的,同时要求方法为静态

loadType可选参数,用来决定方法在场景加载前还是后调用

using UnityEngine;
public class ExampleClass : MonoBehaviour
{
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    static void OnBeforeSceneLoadRuntimeMethod()
    {
        Debug.Log("Before first Scene loaded");
    }

    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    static void OnAfterSceneLoadRuntimeMethod()
    {
        Debug.Log("After first Scene loaded");
    }

    [RuntimeInitializeOnLoadMethod]
    static void OnRuntimeMethodLoad()
    {
        Debug.Log("RuntimeMethodLoad: After first Scene loaded");
    }
}

[SelectionBase]

当一个GameObject含有使用了该属性的Component的时候,在SceneView中选择该GameObject,Hierarchy上面会自动选中该GameObject的Parent

[SharedBetweenAnimators]

用于StateMachineBehaviour上,指定该StateMachineBehavior只实例化一次,不同的Animator将共享这一个StateMachineBehaviour的实例,可以减少内存占用

[UnityAPICompatibilityVersion]

用来声明API的版本兼容性

[CallbackOrderAttribute]

定义Callback的顺序

[UnityAPICompatibilityVersion]

用来声明API的版本兼容性

[CanEditMultipleObjects]

Editor同时编辑多个Component的功能

[CustomPreview(typeof(GameObject))]

将一个class标记为指定类型的自定义预览

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyObject : MonoBehaviour {
}


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEditor;

[CustomPreview(typeof(MyObject))]
public class MyPreview : ObjectPreview {

    public override bool HasPreviewGUI() {
        return true;
    }

    public override void OnPreviewGUI(Rect r, GUIStyle background) {
        GUI.Label(r, target.name + " is being previewed");
    }
}

[CustomPropertyDrawer]

标记自定义PropertyDrawer时候使用。当自己创建一个PropertyDrawe或者DecoratorDrawer的时候,使用该属性来标记

[DrawGizmo (GizmoType.Selected | GizmoType.Active)]

以在Scene视图中显示自定义的Gizmo,Gizmo的图片需要放入Assets/Gizmo目录中

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyScript : MonoBehaviour {
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEditor;

public class MyScriptGizmoDrawer {

    [DrawGizmo(GizmoType.Selected | GizmoType.Active)]
    static void DrawGizmoForMyScript(MyScript scr, GizmoType gizmoType) {
        Vector3 position = scr.transform.position;

        if (Vector3.Distance(position, Camera.current.transform.position) > 10f)
            Gizmos.DrawIcon(position, "MyScript Gizmo.png", true);
    }
}

[InitializeOnLoad]

在Class上使用,可以在Unity启动的时候,运行Editor脚本。需要该Class拥有静态的构造函数。

[InitializeOnLoadMethod]

在Method上使用,是InitializeOnLoad的Method版本。Method必须是static的

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

/// <summary>
/// https://docs.unity3d.com/ScriptReference/InitializeOnLoadAttribute.html
///
/// Allows you to initialize an Editor class when Unity loads,
/// and when your scripts are recompiled.
/// Static constructors with this attribute are called
/// when scripts in the project are recompiled (also known as a Domain Reload).
/// when Unity first loads your project,
/// but also when Unity detects modifications to scripts
/// (depending on your Auto Refresh preferences),
/// and when you enter Play Mode (depending on your Play Mode configuration).
/// </summary>

// Running Editor Script Code on Launch
[InitializeOnLoad]
public class InitializeOnLoadExample
{
    static InitializeOnLoadExample()
    {
        /// https://docs.unity3d.com/Manual/RunningEditorCodeOnLaunch.html

        //Debug.Log("Up and running");

        // editor frame update

        //EditorApplication.update += Update;
    }

    //static void Update() {
    //    Debug.Log("Updating");
    //}

    [InitializeOnLoadMethod]
    static void OnProjectLoadedInEditor()
    {
        /// https://docs.unity3d.com/ScriptReference/InitializeOnLoadMethodAttribute.html

        //Debug.Log("Project loaded in Unity Editor");
    }
}

[OnOpenAsset()]

在打开一个Asset后被调用

using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;

public class MyAssetHandler
{
    [OnOpenAssetAttribute(1)]
    public static bool step1(int instanceID, int line)
    {
        string name = EditorUtility.InstanceIDToObject(instanceID).name;
        Debug.Log("Open Asset step: 1 (" + name + ")");
        return false; // we did not handle the open
    }

    // step2 has an attribute with index 2, so will be called after step1
    [OnOpenAssetAttribute(2)]
    public static bool step2(int instanceID, int line)
    {
        Debug.Log("Open Asset step: 2 (" + instanceID + ")");
        return false; // we did not handle the open
    }
}

[PostProcessBuild(n)]

使用该属性的函数,在build完成后被调用。同时具有多个的时候,可以通过n指定先后顺序。

using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;

public class MyBuildPostprocessor {
    [PostProcessBuildAttribute(1)]
    public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {
        Debug.Log( pathToBuiltProject );
        }
}

[PostProcessScene()]

使用该属性的函数,在scene构建完成之后被调用。具体使用方法和PostProcessBuild类似

using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;

public class MyScenePostprocessor {
    [PostProcessSceneAttribute (2)]
    public static void OnPostprocessScene() {
        GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        cube.transform.position = new Vector3(0.0f, 0.5f, 0.0f);
    }
}

参考资料

Unity Documentation

Unity-Attributes-Example

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值