unity3d Attribute的探索

一.自定义特性

解释:特性可以针对类或者方法,事件去定义

在这里插入图片描述
举例:用处比如unity有很多互相绑定的组件,比如RequireComponent这个特性,其实我们自己也可以定义

[AttributeUsage(AttributeTargets.Class)]
public class ComponentRelationAttribute : Attribute
{
    public List<ComponentClass> enumClass;
    public ComponentRelationAttribute(params ComponentClass[] enumgd)
    {
        if (enumClass == null)
            enumClass = new List<ComponentClass>();
        enumClass.AddRange(enumgd);
    }
    public ComponentRelationAttribute(List<ComponentClass> enums)
    {
        enumClass = enums;
    }
}
public static class ComponentRelationAttributeExtensions
{
    static ComponentRelationAttributeExtensions()
    {
        AddMutualComponent(ComponentClass.SingPersonActionSave, new List<ComponentClass> { ComponentClass.DoublePersonActionSave });
        AddMutualComponent(ComponentClass.DoublePersonActionSave, new List<ComponentClass> { ComponentClass.SingPersonActionSave });
        AddMutualComponent(ComponentClass.VideoBinderSave, new List<ComponentClass> { ComponentClass.PictureCollectSave });
        AddMutualComponent(ComponentClass.PictureCollectSave, new List<ComponentClass> { ComponentClass.VideoBinderSave });
    }
    private static System.Type[] GetComponentRelation;
    private static Dictionary<ComponentClass, List<Type>> passiveRelation = new Dictionary<ComponentClass, List<Type>>();//被动关联
    public static Dictionary<ComponentClass, List<Type>> PassiveRelation => passiveRelation;
    public static Type[] GetRelationAttribute()
    {
        if (GetComponentRelation != null)
        {
            return GetComponentRelation;
        }
        System.Reflection.Assembly asm = System.Reflection.Assembly.GetAssembly(typeof(ComponentRelationAttribute));
        System.Type[] types = asm.GetExportedTypes();

        Func<Attribute[], Type, bool> IsMyAttribute = (o, v) =>
         {
             foreach (Attribute a in o)
             {
                 if (a is ComponentRelationAttribute)
                 {
                     var cab = a as ComponentRelationAttribute;

                     for (int i = 0; i < cab.enumClass.Count; i++)
                     {
                         // initiativeRelation[v].Add(cab.enumClass[i]);
                         if (!passiveRelation.ContainsKey(cab.enumClass[i]))
                         {
                             passiveRelation[cab.enumClass[i]] = new List<Type>();
                         }
                         Type[] Generic = v.BaseType.GetGenericArguments();
                         if (Generic.Length > 0)
                         {
                             var rcd = Generic[0];
                             passiveRelation[cab.enumClass[i]].Add(rcd);

                         }

                     }
                     return true;
                 }

             }
             return false;
         };

        GetComponentRelation = types.Where(o =>
        {
            return IsMyAttribute(System.Attribute.GetCustomAttributes(o, true), o);
        }
        ).ToArray();
        return GetComponentRelation;
    }
    /// <summary>
    /// 是否能够移出组件
    /// </summary>
    /// <param name="datas"></param>
    /// <param name="closeEnum"></param>
    /// <returns></returns>
    public static bool IsEnableClose(List<ComponentData> datas, ComponentClass closeEnum)
    {
        GetRelationAttribute();
        bool isenable = true;
        if (passiveRelation.ContainsKey(closeEnum))
        {
            //被动关联
            var types = passiveRelation[closeEnum];
            //  var cv= removeType.GetComponents<ComponentView>();
            //  var typeList=  cv.ToList();
            for (int i = 0; i < datas.Count; i++)
            {
                if (types.Contains(datas[i].GetType()))
                {
                    isenable = false;
                }
            }
        }
        return isenable;
    }
    private static Dictionary<ComponentClass, List<ComponentClass>> DicMutualComponent = new Dictionary<ComponentClass, List<ComponentClass>>();
    #region 互斥组件
    /// <summary>
    /// 不能同时添加的两个组件 数据收集
    /// </summary>
    /// <param name="arg1"></param>
    /// <param name="arg2"></param>
    private static void AddMutualComponent(ComponentClass arg1, List<ComponentClass> arg2)
    {
        DicMutualComponent[arg1] = arg2;
    }
    /// <summary>
    /// 检查是否存在互斥的组件
    /// </summary>
    /// <param name="arg1"></param>
    /// <param name="arg2"></param>
    /// <returns></returns>
    public static bool MutualComponentState(ComponentClass arg1, ComponentClass arg2)
    {
        bool ismutual = false;
        if (DicMutualComponent.ContainsKey(arg2))
        {
            var mus = DicMutualComponent[arg2];
            foreach (var m in mus)
            {
                if (m == arg2)
                    ismutual = true;
            }
        }
        return ismutual;
    }
    #endregion

}

//关联组件绑定到对应需要的类中
[ComponentRelation(ComponentClass.BoxExtendSave, ComponentClass.IconPositonSave)]
public class PictureBinderComponentView : ComponentAutoBase<PictureCollectSaveData>
{
	/// <summary>
    /// 检查是否需要添加关联组件
    /// </summary>
    private void AddLoadRelationComponent()
    {
        var cra = (ComponentRelationAttribute)this.GetType().GetCustomAttributes(typeof(ComponentRelationAttribute), true).FirstOrDefault();
        if (cra != null && cra.enumClass != null)
        {
            for (int i = 0; i < cra.enumClass.Count; i++)
            {
              //do... 判断是否有此关联组件数据,没有添加关联的组件以及数据
            }
        }
    }
}

二.unity特性

1.AddComponentMenu
   直面解释就是这个脚本能够在Component菜单栏里找到
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("Transform/Follow Transform")]
public class Follow : MonoBehaviour
{
   
}

2.BeforeRenderOrderAttribute
当您需要为Application.onBeforeRender指定自定义回调顺序时,请使用此BeforeRenderOrderAttribute
重新排列调用函数顺序
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[AddComponentMenu("Transform/Follow Transform")]
public class Follow : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
       
        Application.onBeforeRender += Test2;
        Application.onBeforeRender += Test1;
    }

   
    [BeforeRenderOrder(0)]
    public void Test1()
    {
      Debug.Log($"Test1");
    }
    [BeforeRenderOrder(1)]
    public void Test2()
    {
        Debug.Log($"Test2");
    }
}

3.ColorUsageAttribute
在“color”上使用此属性可将“颜色字段”和“颜色选择器”配置alpha值(显示/隐藏),以及将该颜色视为HDR颜色还是普通 LDR颜色。
//第一个参数为是否显示alpha 第二个参数是否为HDR渲染颜色
 [ColorUsage(false,false)]
    public Color Test_color1;
    [ColorUsage(true,true)]
    public Color Test_Color2;
4.ContextMenu和ContextMenuItem
ContextMenu在附加脚本的检查器中,当选择是执行方法
ContextMenuItem 右击当前属性,调用方法

在这里插入图片描述

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

[AddComponentMenu("Transform/Follow Transform")]
public class Follow : MonoBehaviour
{
    // Start is called before the first frame update
    [ColorUsage(false,false)]
    public Color Test_color1;
    [ColorUsage(true,true)]
    public Color Test_Color2;
    void Start()
    {
     
    }
    [ContextMenu("左键名字")]
    void message()
    {
        Debug.Log("ContextMenu1");
    }
    [ContextMenuItem("调用方法","message2")]
    public string testName = "";
    void message2()
    {
        testName = "hide";
        Debug.Log($"{testName}");
    }
   
}
5.CreateAssetMenuAttribute
将一个ScriptableObject派生类型标记为自动在Assets / Create子菜单中列出,以便可以轻松创建该类型的实例并将其存储为“ .asset”文件。

在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName ="创建资源",menuName ="Tools",order =1)]
public class creatasset : ScriptableObject 
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

6.CreateAssetMenuAttribute
[参考链接](https://docs.unity.cn/cn/2019.4/Manual/Tilemap-ScriptableBrushes-Example.html)  https://docs.unity.cn/cn/2019.4/Manual/Tilemap-ScriptableBrushes-Example.html
自定义网格笔刷
7. DelayedAttribute
 用于延迟脚本中的float,int或string变量的属性
 使用此属性时,在用户按下Enter键或将焦点从该字段移开之前,float,int或text字段将不会返回新值。
 比如下面的代码:
    没有Delayed属性时输入参数时会打印依次输入的参数,而定义了Delayed 只有不聚焦离开或者按下enter时,他打印的值
    才会改变
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[AddComponentMenu("Transform/Follow Transform")]
public class Follow : MonoBehaviour
{
    [Delayed()]
    public int testint=0;

    private void Update()
    {
        Debug.Log(testint);
    }
}
8. DisallowMultipleComponent
 防止将相同类型(或子类型)的MonoBehaviour多次添加到GameObject中。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[DisallowMultipleComponent]
[AddComponentMenu("Transform/Follow Transform")]
public class Follow : MonoBehaviour
{
   // [Delayed()]
    public int testint=0;
    void Start()
    {
     
    }

    private void Update()
    {
     
    }
}
9. ExcludeFromObjectFactoryAttribute
作用于类上,禁止该类及其子类被 ObjectFactory 的方法创建
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using  UnityEditor;

public class test : Editor
{
    [MenuItem("Tests/ObjectFactory")]
    public static void test1()
    {
        ObjectFactory.CreateInstance(typeof(Follow));
    }
}


using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExcludeFromObjectFactory]
public class Follow : MonoBehaviour
{
   // [Delayed()]
    public int testint=0;
    void Start()
    {
     
    }

    private void Update()
    {
        Debug.Log(testint);
    }
}
10. ExcludeFromPresetAttribute
将此属性添加到类中,以防止从该类的实例创建preset(预设)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//ExcludeFromPreset 加与不加可以看到效果
[ExcludeFromPreset]
public class Follow : MonoBehaviour
{
   // [Delayed()]
    public int testint=0;
    void Start()
    {
     
    }

    private void Update()
    {
        Debug.Log(testint);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using  UnityEditor;
using UnityEditor.Presets;


public class test : Editor
{
    [MenuItem("Tests/ObjectFactory")]
    public static void test1()
    {
        GameObject gat = Selection.activeGameObject;
        if(!gat.GetComponent(typeof(Follow)))
       ObjectFactory.AddComponent<Follow>(gat);
        Object ga = gat.GetComponent<Follow>();
        CreatePresetAsset(ga, ga.name);
    }
    public static void CreatePresetAsset(UnityEngine.Object source, string name)
    {
        Preset preset = new Preset(source);
        AssetDatabase.CreateAsset(preset, "Assets/" + name + ".preset");
    }
}
11. ExecuteAlways
作用于类上,使实例对象脚本无论在 Edit Mode、 Play Mode 都执行;
注意区分 Edit Mode 和 Play Mode 代码执行逻辑,Edit Mode 下 Update
仅在 Scene 更改时执行,OnGUI 仅在接收到
"仅限Editor之外事件"时(如:EventType.ScrollWheel)且不响应Editor快捷键,
OnRenderObject 和其他渲染回调方法在场景重绘时调用。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteAlways]
public class Follow : MonoBehaviour
{
    void Start()
    {
        if (Application.IsPlaying(this))
        {
            Debug.Log("seeyou");
        }
        else
        {
            Debug.Log("再见");
        }
    }

    private void Update()
    {
      
    }
}
12. ExecuteInEditMode
作用于类上,使脚本实例在 Edit Mode 下执行,同 ExecuteAlways ,模式只不过区分了
13. GradientUsageAttribute
作用于 Gradient 类型变量上,参数:hdr 是否使用 HDR  与ColorUsageAttribute使用差不多,不过多解释了
14. GUITargetAttribute
允许控制调用OnGUI的显示。

在这里插入图片描述

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Follow : MonoBehaviour
{
   // [Delayed()]
    public int testint=0;
    void Start()
    {
      
    }
    //Display下标 为0 和1
   [GUITarget(0,2)]
    private void OnGUI()
    {
       GUI.Label(new Rect(new Vector2(30,30),new Vector2(300,20)),"在game1和3窗口显示");
    }

    private void Update()
    {
      
    }
}
15. HeaderAttribute
作用于变量上,给变量在 Inspector 中添加标题头

在这里插入图片描述

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Follow : MonoBehaviour
{
   [Header("测试")]
    public int testint=0;
}
16. HelpURLAttribute
 提供类的自定义文档URL。给定一个链接
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[HelpURL("http://baidu.com")]
public class Follow : MonoBehaviour
{
}
17.HideInInspector
变量不显示在Inspector面板上,但可被序列化
18.ImageEffectTransformsToLDR
在使用 HDR 渲染条件下,渲染 Image Effect 切换到 LDR 渲染
19.InspectorNameAttribute
作用于枚举值,更改枚举值在 Inspector 上显示的名称

在这里插入图片描述

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

[HelpURL("http://baidu.com")]
public class Follow : MonoBehaviour
{
    public test_enum TestEnum;

    public enum test_enum
    {
        test0 = 0,
        [InspectorName("测试1")]
        test1 = 1,
        [InspectorName("测试2")]
        test2 = 2,
    }
}
20.MinAttribute
用于使脚本中的float或int变量的属性限制为特定的最小值。
21.MultilineAttribute
 用于使用多行文本字段编辑字符串的属性。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

[HelpURL("http://baidu.com")]
public class Follow : MonoBehaviour
{
    [Min(10)]
    public int testint;

    [Multiline(20)] 
    public string teststring;
}
22.PreferBinarySerialization
作用于 ScriptableObject 派生类,使用二进制序列化取代项目资源序列化,可提升读写效率,
提高压缩表现且无法直接识别,但当资源文件包含多个资源时无法使特定资源使用二进制序列化,
嵌入场景的组员也会无视二进制序列化
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName ="创建资源",menuName ="Tools",order =1)]
[PreferBinarySerialization]
public class creatasset : ScriptableObject 
{
    public float[] lotsOfFloatData = new[] { 1f, 2f, 3f };
    public byte[] lotsOfByteData = new byte[] { 4, 5, 6 };
}

24. NonReorderableAttribut
在inspector窗口中禁用对数组或列表的重新排序。默认情况下,数组或列表脚本变量带有一个UI控件,
该控件允许通过元素内容左侧的拖动手柄对数组元素进行重新排序。您可以在脚本数组或列表变量上使用
[NonReorderable]属性来禁用此功能。禁用重新排序后,Inspector会使用简单的UI控件显示数组或列表,
该UI控件的大小为数组大小,后跟数组元素。
using UnityEngine;

public class NonReorderableAttributeTest : MonoBehaviour
{
    [NonReorderable]
    public int[] array;
}
23.PropertyAttribute
自定义特性的基类,用于创建自定义特性派生类
24.RangeAttribute
作用于 int 和 float 变量,限制范围值,在 Inspector 上显示范围条

[Range(2, 7)]
public int rangValue;
25.RequireComponent
 作用于类, 在挂载该脚本同时会自动挂载该脚本依赖的组件,且删除时弹出警告
26.RuntimeInitializeOnLoadMethodAttribute
 允许在运行时加载游戏而无需用户采取行动的情况下初始化运行时类方法。
  [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    public static void BeforeSceneLoad()
    {
        Debug.Log("场景启动之前调用");
    }
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    public static void AfterSceneLoad()
    {
        Debug.Log("场景启动之后调用");
    }
27.SelectionBaseAttribute
作用于类,使被挂载的 GameObject 优先被选中;如当前 GameObject 为子物体,
当点击该物体时会默认选中父物体,在该特性脚本挂载到子物体后会优先选中子物体
28.SerializeField
 作用于所有类型,被标记的私有类、变量等会被强制序列化(非静态),显示在inspector面板
29.SerializeReference
作用于引用对象,使 Unity 序列化对象为引用类型;
Unity 默认除 UnityEngine.Object 派生类以外类型都序列化为值类型
30.SpaceAttribute
 作用于所有字段,在 Inspector 添加空行像素 
31.TextAreaAttribute
参数:maxLines 最大行、minLines 最小行
作用于 string 类型,在 Inspector 添加高度灵活可滑动的文本区
32.TooltipAttribute
 作用于字段,为字段在 Inspector 添加悬浮解释文字

在这里插入图片描述

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

namespace Test
{
    public class Follow : MonoBehaviour
    {
        [Tooltip("This is a Tooltip")] public String tooltip;
    }
   
}


33.NonSerialized
 NonSerialized 属性将变量标记为无法序列化。通过该方法,您可以使一个变量保持公开,
 且 Unity 不会尝试序列化它或在 Inspector 中显示它。功能与HideInInspector差不多
34.Serializable
 指示可序列化的类或结构。要启用序列化,则应用 [Serializable] 属性
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace Test
{
    public class Follow : MonoBehaviour
    {
        [SerializeField]
        private PlayerStats stats;
        [NonSerialized]
        public float values;
    }
    [Serializable]
    public struct PlayerStats
    {
        public int movementSpeed;
        public int hitPoints;
        public bool hasHealthPotion;
    }
}


34.CanEditMultipleObjects
用于Editor同时编辑多个Component的功能,在选择了多个对象后,不具有此属性的编辑器将会显示
"Multi-object editing not supported"消息
35.CustomEditor

这个大家应该很熟悉,不过多解释,操作component组件,重新排版功能

36.CustomEditorForRenderPipelineAttribute
为自定义编辑器在更改RenderPipeline时,需要将此属性放在该类上。
37.CustomPreviewAttribute
在检视面板中为指定的类型添加额外的预览。您可以使用此属性将自定义预览添加到可进行检查的任何对象中。
using System.Collections;
using System.Collections.Generic;
using Test;
using UnityEngine;
using  UnityEditor;

[CustomPreview(typeof(Follow))]
public class test : ObjectPreview
{
   /// <summary>
   ///  能否在当前状态下预览此组件?
   /// </summary>
   /// <returns></returns>
   public override bool HasPreviewGUI()
   {
      return true;
   }
    /// <summary>
    /// 实现为Editor的预览区域创建自己的自定义预览,
    /// </summary>
    /// <param name="r"></param>
    /// <param name="background"></param>
   public override void OnPreviewGUI(Rect r, GUIStyle background)
   {
       Debug.Log("查看");
   }
}


38.CustomPropertyDrawer
告知自定义 PropertyDrawer 或 DecoratorDrawer 该绘制器所针对的运行时 Serializable 类或
 PropertyAttribute.
 详细可参考https://docs.unity3d.com/ScriptReference/PropertyDrawer.html,
 里面讲述了如何创建一个PropertyAttribute以及创建后如何绘制(在inspector面板显示)
using System.Collections;
using System.Collections.Generic;
using Test;
using UnityEngine;
using  UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;

//可以使用自定义 PropertyDrawer 来更改 Inspector 中 Ingredient 类的每个外观。
//您可以使用 CustomPropertyDrawer 特性将 PropertyDrawer 附加到 Serializable 类,然后传入绘制器所对应的 Serializable 类的类型。
//以下是使用 IMGUI 写入的自定义 PropertyDrawer 的示例:比较不带有和带有自定义 PropertyDrawer 的 Inspector 中 Ingredient 属性的外观:
[CustomPropertyDrawer(typeof(Ingredient))]
public class test : PropertyDrawer
{
    // Draw the property inside the given rect
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        // Using BeginProperty / EndProperty on the parent property means that
        // prefab override logic works on the entire property.
        EditorGUI.BeginProperty(position, label, property);

        // Draw label
        position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);

        // Don't make child fields be indented
        var indent = EditorGUI.indentLevel;
        EditorGUI.indentLevel = 0;

        // Calculate rects
        var amountRect = new Rect(position.x, position.y, 30, position.height);
        var unitRect = new Rect(position.x + 35, position.y, 50, position.height);
        var nameRect = new Rect(position.x + 90, position.y, position.width - 90, position.height);

        // Draw fields - passs GUIContent.none to each so they are drawn without labels
        EditorGUI.PropertyField(amountRect, property.FindPropertyRelative("amount"), GUIContent.none);
        EditorGUI.PropertyField(unitRect, property.FindPropertyRelative("unit"), GUIContent.none);
        EditorGUI.PropertyField(nameRect, property.FindPropertyRelative("name"), GUIContent.none);

        // Set indent back to what it was
        EditorGUI.indentLevel = indent;
        EditorGUI.EndProperty();
    }
}


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

namespace Test
{
    public class Follow : MonoBehaviour
    {
       public Ingredient potionResult;
        public Ingredient[] potionIngredients;
    }
    [Serializable]
    public class Ingredient
    {
        public string name;
        public int amount = 1;
        public IngredientUnit unit;
    }
    public enum IngredientUnit { Spoon, Cup, Bowl, Piece }
}


39.DrawGizmo
DrawGizmo 属性可用于为任意 Component 提供辅助图标渲染器。渲染器函数必须是静态的,并且采用两个参数:
一个是 绘制辅助图标所面向的对象,另一个是 GizmoType 参数,表示绘制辅助图标时所处的上下文。
渲染器函数可在任何类中定义,包括编辑器脚本。因此, 您可以将辅助图标绘制代码与组件脚本分离,
从而 使其不会包含在构建中。

在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using Test;
using UnityEngine;
using  UnityEditor;
public class test 
{
    [DrawGizmo(GizmoType.Selected | GizmoType.Active)]
    static void DrawGizmoForMyScript(Follow scr, GizmoType gizmoType)
    {
        Vector3 position = scr.transform.position;

        if (Vector3.Distance(position, Camera.current.transform.position) > 10f)
        {
            Gizmos.color=Color.green;
            Gizmos.DrawLine(position, new Vector3(0,0,200));  
        }
          
    }
}


40.InitializeOnEnterPlayModeAttribute
允许在 Unity 进入运行模式时初始化编辑器类方法。用于在进入运行模式时重置 Editor 类中的静态字段,
而不进行域重新加载。
using System.Collections;
using System.Collections.Generic;
using Test;
using UnityEngine;
using  UnityEditor;
public class test
{
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    private static void BeforeSceneLoad()
    {
        Debug.Log("场景播放之前");
    }
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    private static void AfterSceneLoad()
    {
        Debug.Log("场景播放之后");
    }

    [InitializeOnEnterPlayMode]
    public static void OnEnterPlaymodeInEditor(EnterPlayModeOptions options)
    {
        Debug.Log("进入播放"+options);
    }
}


41.InitializeOnLoadAttribute
允许在 Unity 加载时和重新编译脚本时初始化 Editor 类。重新编译项目中的脚本时,
会调用带有此属性的静态构造函数(也称为域重新加载)。在 Unity 首次加载项目时、
在 Unity 检测到脚本修改时(取决于自动刷新首选项),以及当进入运行模式时(取决于运行模式配置),
会进行此调用。
using System.Collections;
using System.Collections.Generic;
using Test;
using UnityEngine;
using  UnityEditor;
[InitializeOnLoad]
internal class test
{
   /// <summary>
   /// 必须为静态构造函数
   /// </summary>
   static test()
   {
      Debug.Log("开始运行");
      EditorApplication.update += Hotfix;
   }

   private static void Hotfix()
   {
      Debug.Log("更新");
   }
}


42.InitializeOnLoadMethod
根据名子就知道他是针对方法的 与InitializeOnLoad一样,必须是静态的
using System.Collections;
using System.Collections.Generic;
using Test;
using UnityEngine;
using  UnityEditor;
//[InitializeOnLoad]
internal class test
{
   /// <summary>
   /// 必须为静态构造函数
   /// </summary>
   static test()
   {
     // Debug.Log("开始运行");
      //EditorApplication.update += Hotfix;
   }
   [InitializeOnLoadMethod]
   public static void Hotfix()
   {
      Debug.Log("更新");
   }
}


43.LightingExplorerExtensionAttribute
用于标记 Lighting Explorer 的扩展类的属性。每个渲染管线仅支持一个扩展。
44.MenuItem
 在方法上使用,可以在Editor中创建一个菜单项,点击后执行该方法,可以利用该属性做很多扩展功能
 要创建热键,您可以使用以下特殊字符:%(在 Windows 上为 ctrl,在 macOS 上为 cmd)、# (shift)、& (alt)。
 如果不需要特殊的修改键组合,该键可以在下划线后给出。
 例如,要创建一个带有热键 shift-alt-g 的菜单,可以使用“MyMenu/Do Something #&g”。
 要创建带有热键 g 而不按下修改键的菜单,则使用“MyMenu/Do Something _g”。
(很常见的一种功能,写过编辑器的应该都了解, 不过多解释了)
MenuItem("Tools/Setting #&J", priority = 1998)]
45.SettingsProviderAttribute
用于注册新 SettingsProvider 的属性。使用此属性可以修饰返回 SettingsProvider 实例的函数。
如果函数返回 null, 则 Settings 窗口中不会显示 SettingsProvider。

在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using System.IO;
using Test;
using UnityEngine;
using  UnityEditor;
class test:SettingsProvider
{
    const string k_MyCustomSettingsPath = "Assets/heihei.asset";
    public test(string path, SettingsScope scope)
        : base(path, scope) {}

    public static bool IsSettingsAvailable()
    {
        return File.Exists(k_MyCustomSettingsPath);
    }

    [SettingsProvider]
    public static SettingsProvider CreateMyCustomSettingsProvider()
    {
        Debug.Log(IsSettingsAvailable());
        if (IsSettingsAvailable())
        {
            return new test("test", SettingsScope.Project);
        }

        // Settings Asset doesn't exist yet. No need to display anything in the Settings window.
        return null;
    }
}
46.SettingsProviderGroupAttribute
用于注册多个 SettingsProvider 项的属性。使用此属性可以修饰返回一组 SettingsProvider 实例的函数。
如果函数返回 null,则 Settings 窗口中不会显示 SettingsProvider。
using System.IO;
using System.Linq;
using UnityEditor;

class XRSettings : SettingsProvider
{
    const string k_XRSettingsFolder = "Assets/Editor/XRSettings";
    public XRSettings(string path, SettingsScope scope = SettingsScope.Project)
        : base(path, scope)
    {
    }

    [SettingsProviderGroup]
    public static SettingsProvider[] CreateProviders()
    {
        var files = Directory.GetFileSystemEntries(k_XRSettingsFolder, "*.json");
        return files.Select(entry =>
        {
            // First parameter is the path of the settings in the Settings window.
            return new XRSettings("Project/XRSettings/" + Path.GetFileNameWithoutExtension(entry));
        }).ToArray();
    }
}
47.PostProcessSceneAttribute
将此属性添加到方法中,以在构建场景后立即获得通知。
  [PostProcessSceneAttribute (2)]
    public static void OnPostprocessScene() {
        GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        cube.transform.position = new Vector3(0.0f, 0.5f, 0.0f);
    }
48.PostProcessBuildAttribute
将此属性添加到一种方法,以便在build后立即获得通知
  [PostProcessBuildAttribute(1)]
    public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {
        Debug.Log( pathToBuiltProject );
        }
49.OnOpenAssetAttribute
用于在Unity中打开资产的回调属性(例如,在项目浏览器中双击资产时会触发回调)
 [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
    }

    //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
    }
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值