找回密码
 立即注册
查看: 381|回复: 0

Unity编辑器拓展学习,(1)特性更新完毕

[复制链接]
发表于 2023-4-3 20:54 | 显示全部楼层 |阅读模式
一 . Unity编辑器特性集合(这个也是编辑器扩展的一部分吧)

AddComponentMenu -> 添加脚本到Component

将一个脚本添加到Component菜单中,然后所以可以通过Component->(我设置名字)来为你选中的物体添加这个脚本。
官方介绍:使用 AddComponentMenu 属性可在“Component”菜单中的任意位置放置脚本,而不仅是“Component > Scripts”菜单。



这个平时还不算很常用



然后就可以在Component上找到自己定义的名字

但是这个名字有可能是灰色的,因为没有选中场景中的物体。(0.0)
写法//StudyOne == 名字  1 = 层级
[AddComponentMenu("StudyOne",1)]

AssemblyIsEditorAssembly ->具有该属性的程序集中的任何类都将被视为编辑器类

程序集级别的属性。具有该属性的程序集中的任何类都将被视为编辑器类。
(暂不清晰用法)
BeforeRenderOrderAttribute ->自定义渲染前回调的顺序

当您需要为 Application.onBeforeRender 指定自定义回调顺序时,使用此 BeforeRenderOrderAttribute。
Application.onBeforeRender 将对所有已注册的事件接收器进行重新排序,然后根据此属性按从低到高的顺序调用它们。无属性代表顺序 0。
Application.onBeforeRender可以用来自定义渲染前回调的顺序


打印结果


为方法添加[BeforeRenderOrder()]特性后




    [BeforeRenderOrderAttribute(0)] //这个参数会被简化名称变为
    [BeforeRenderOrder(1)]
ColorUsageAttribute -> 用于显示处理HDR颜色

官方描述: 属性,用于为颜色配置 ColorField 和拾色器的使用情况。
对 Color 使用此属性可将 Color Field 和拾色器配置为显示/隐藏 alpha 值,以及将颜色处理为 HDR 颜色还是正常 LDR 颜色。



使用



可以用于显示HDR

    [ColorUsage(true, true)]//这个特性拥有多个重载,当前为,showAlpha,HDR
ContextMenu ->用于在编辑器环境中执行脚本方法

ContextMenu 属性用于向上下文菜单添加命令。
在该附加脚本的 Inspector 中,当用户选择该上下文菜单时, 将执行此函数。

这对于从该脚本自动设置场景数据非常有用。 此函数必须是非静态的。



使用方法,C#是最好的语言



下面多出了一个按钮



点击执行方法

这个特性的用处很多,比如你想把一千个物体一起改名,改变位置之类的时候。QAQ
ContextMenuItemAttribute -> 给字段添加右键方法

使用该属性可将上下文菜单添加到调用命名方法的字段。



代码



右键菜单新增按钮



点击方法

CreateAssetMenuAttribute -> 在右键菜单中快速添加创建Scriptableobject

对 ScriptableObject 派生类型进行标记,使其自动列在 Assets/Create 子菜单中,以便能够轻松创建该类型的实例并将其作为“.asset”文件存储在项目中。



使用这个特性,需要脚本继承Scriptableobject这样可以快速的创建脚本资源



右键创建彩蛋中出现按钮



创建脚本物体

CustomGridBrushAttribute ->自定义可编程网格画笔

属性,用于将该类定义为网格画笔,以及使其在调色板窗口中可用。



需要繼承GridBrushBase類

DelayedAttribute ->延迟变量修改值

属性,用于使脚本中的 float、int 或 string 变量被延迟。
当使用此属性时,直到用户按 Enter 键或将焦点从 float、int 或文本字段移开后,该字段才会返回新值。



使用方法



如官方介绍的一样按下,或者移开注视才会修改值。否则不会修改

DisallowMultipleComponent ->防止相同类型 or子类型的mono脚本多次添加相同物体

防止将相同类型(或子类型)的 MonoBehaviour 多次添加到 GameObject。



使用



效果,重复添加时会报错。

ExcludeFromObjectFactoryAttribute ->禁止objectfactory方法创建类

将此属性添加到某个类可防止使用ObjectFactory方法创建该类及其继承类。
ObjectFactory.CreateInstance 可以用于在任何地方创建类,使用这个特性会禁止使用这个方法创建类。
ExcludeFromPresetAttribute -> 禁止创建挂载类的Preset

将此属性添加到某个类可防止从该类的实例创建Preset
Preset -
一个预设包含一个对象的默认值。
Preset 类包含创建对象时所用的对象类型以及含此对象的每个已序列化属性/值对的列表。 此类可用于在 Editor 中存储任何已序列化对象的信息,并可将这些信息重新应用到此对象或同类型的其他任何对象。 此外,还可以使用 .preset 扩展名将预设另存为资源。
    public static void CreatePresetAsset(Object source, string name)
    {
        Preset preset = new Preset(source);
        AssetDatabase.CreateAsset(preset, "Assets/" + name + ".preset");
    }官方参考方法。



尝试了一下



生成的物体

ExecuteAlways ->即使没有挂载,依旧执行脚本

使脚本的实例在播放模式期间以及编辑时始终执行。
默认情况下,MonoBehaviours 仅在播放模式下并且仅当它们位于包含用户场景的主阶段中的游戏对象上时才执行。它们不会在编辑模式下执行,也不在预制件模式下编辑的对象上执行,即使此时在播放模式下也是如此。通过添加此属性,MonoBehaviour 的任何实例都将始终执行其回调函数。

当您希望脚本作为编辑器工具的一部分执行某些操作时,即可使用 [ExecuteAlways] 属性,不一定要与构建播放器和播放模式中发生的播放逻辑相关。有时,此类脚本的“播放”功能与其“编辑模式”功能相同,而其他情况下则相差很大。

使用此属性的 MonoBehaviour 必须确保它们在编辑模式下或者在对象不是游戏世界的一部分时不会运行可能导致对象被错误修改的播放逻辑。为达到此目的,可以使用 Application.IsPlaying,在其中,脚本可以传入自己的游戏对象以检查它是否是游戏世界的一部分。

如果 MonoBehaviour 在播放模式下运行播放逻辑并且无法检查其游戏对象是否是游戏世界的一部分,则在预制件模式下编辑的预制件可能会被仅用作游戏世界一部分的逻辑错误地修改和保存。

如果您的脚本使用静态变量或单例模式,则应确保属于游戏世界的脚本实例和不属于游戏世界的实例不会通过这些变量或单例意外地相互影响。

在不属于游戏世界的对象上,不会像其他情况那样不断地调用以下函数
官方示例
[ExecuteAlways]
public class ExampleClass : MonoBehaviour
{
    void Start()
    {
        if (Application.IsPlaying(gameObject))
        {
            // Play logic
        }
        else
        {
            // Editor logic
        }
    }
}


挂载了这个特性的脚本,即使没有挂载在场景中,依然会执行。

这个东西可以用作插件的开启页面,以及一些其他的功能。
ExecuteInEditMode

使脚本的所有实例都在编辑模式下执行。
默认情况下,仅在播放模式下执行 MonoBehaviours。通过添加此属性,MonoBehaviour 的任何实例都将在编辑器处于编辑模式时执行其回调函数。

此属性正在逐步被淘汰,因为它不考虑预制件模式。如果在预制件模式下编辑一个带有 MonoBehaviour 并启用了此属性的预制件,然后进入播放模式,则编辑器将退出预制件模式,以防止由仅用于播放模式的逻辑引起的预制件意外修改。

要指示 MonoBehaviour 正确考虑了预制件模式并且在播放模式期间以预制件模式打开是安全的,可以使用属性 ExecuteAlways 取代此处的属性。
GradientUsageAttribute -> 使色彩渐变条显示HDR颜色

此属性用于为渐变配置 GradientField 和渐变编辑器的使用情况。



此是配合Gradlent来使用的,在渐变色彩条上显示HDR颜色



true HDR,flase 普通色彩条

GUITargetAttribute -> 不清楚的GUi特效

允许控制针对哪个显示屏调用 OnGUI。
不太了解,应该是针对于GUI的特性。但是介绍尝试失败了。
HeaderAttribute ->在字段上增加标题

[Header("Hpdata 血量值")]
public int hp;
这个是很常用的一个特性,用于在inspector中的一些字段上方添加标题。





显示了一个标题。

HelpURLAttribute -> 为类提供一个URL




使用方法也很简单

就是一个用来打开网页的特性,用于写工具时会很有用。
HideInInspector -> 在inspector中隐藏公开字段,但依旧会序列化




添加了这个特性,在面板上就不会再显示这个字段了。


IconAttribute -> 指定图标

——————找了半天没找到具体做法,晚了,今日就到这里, 2023/3/29日 23.54
怀疑这个特性其实就是这个功能

ImageEffectAfterScale -> 图像效果以全分辨率的形式出现

任何具有该属性的图像效果都将在动态分辨率阶段后渲染。
如果您希望在动态分辨率按比例缩放后应用图像效果,请添加该属性。效果将以全分辨率呈现,对于在某种程度上依赖于屏幕宽度和高度为特定大小的效果来说,这非常重要。
这个东西目前没有应用得到,如果可以后期会补上。
ImageEffectAllowedInSceneView -> 图像渲染Scene视图摄像机

任何具有该属性的图像效果都可以渲染到 Scene 视图摄像机中。
如果您希望将图像效果应用于 Scene 视图摄像机,请添加该属性。效果将在相同的位置应用,并且与来自开启该效果的摄像机的值相同。
ImageEffectOpaque ->调整图像效果渲染顺序

任何具有该属性的图像效果都将在不透明几何形状之后但在透明几何形状之前渲染。
这使得大量使用深度缓冲器(SSAO 等)的效果仅影响不透明像素。该属性可用于通过后期处理减少场景中的视觉瑕疵。
ImageEffectTransformsToLDR -> 将图像渲染效果切换至LDR模式

使用 HDR 渲染时,有时可能需要在 ImageEffect 渲染期间切换到 LDR 渲染。
对图像效果使用该属性将使目标缓冲区成为 LDR 缓冲区, 并将剩余的图像效果管线切换到 LDR 模式。与该属性关联的图像效果负责 确保输出处于 LDR 范围内。
这个也就是将高色彩HDR,变成LDR色彩,
ImageEffectUsesCommandBuffer -> 当图像效果是用 Command Buffer 实现的时,使用此属性

当图像效果是用 Command Buffer 实现的时,请使用此属性。
使用此属性时,Unity 将场景渲染到 RenderTexture 而不是实际目标中。请注意,Camera.forceIntoRenderTexture 可能有同样的效果,但仅限于某些情况。
emmm 图像渲染还没有学习多少,看不太懂这里。
InspectorNameAttribute -> 改变枚举值在inspector中显示的名称

对枚举值声明使用此属性可更改 Inspector 中显示的显示名称。
public enum ModelImporterIndexFormat
{
    Auto = 0,
    [InspectorName("16 bits")]
    UInt16 = 1,
    [InspectorName("32 bits")]
    UInt32 = 2,
}
//官方事例



简单测试



Yes

MinAttribute ->用于使脚本中的 float 或 int 变量受限于特定最小值的属性。

用于使脚本中的 float 或 int 变量受限于特定最小值的属性。
它说的很对,没什么可以修改的。



使用



这两个数值没法赋值小于0的值了。

MultilineAttribute -> 使用多行文本在ins面板中编辑字符串

用于通过多行文本字段编辑字符串的属性。



使用



效果

NonReorderableAttribute -> 禁止在面板中重新排序数组

Disables reordering of an array or list in the Inspector window.
By default, array or list script variables are presented with a UI control that allows array element reordering via drag handles to the left of element content. You can use [NonReorderable] attribute on a script array or list variable to disable this. When reordering is disabled, the Inspector shows arrays or lists with a simple UI control that has an array size followed by array elements.



正常情况下,新版这样的List数组是可以随时拖动的。



加入这个特性后



无法进行拖动更改,

PreferBinarySerialization ->对ScriptableObject优先使用二进制序列化

使 ScriptableObject 派生类型优先使用二进制序列化(不考虑项目的资源序列化模式)。
对于包含大量数据的自定义资源类型,这非常有用。始终使它们存储为二进制可以提高读/写性能,以及在磁盘上生成更紧凑的表示。主要缺点是二进制资源文件不再人工可读,并且无法在版本控制软件中将其合并。

Unity 中的资源序列化对每个文件整体始终使用一致的序列化模式。因此,当资源文件包含多个资源时,强制特定资源使用二进制序列化可能无法始终满足。资源文件的序列化模式由该路径上的主资源控制。因此,在使用 AssetDabase.CreateAsset 和 AssetDatabase.AddObjectToAsset 组合复杂资源时必须谨慎,以确保主资源是设置了此属性的对象。场景文件始终遵循在项目中配置的资源序列化模式,因而对于场景中嵌入的资源,会始终忽略 PreferBinarySerialization。

该属性只能应用于 ScriptableObject 派生类,对于所有其他类型,都会被忽略。



测试



没有使用特性创建的文件



使用特性之后创建的

PropertyAttribute ->自定义特性

用于派生自定义属性特性的基类。这可用于为脚本变量创建特性。
自定义特性可以与自定义 PropertyDrawer 类连接,以控制具有该特性的脚本变量如何在 Inspector 中显示。

官方另请参阅:PropertyDrawer 类。
这个特性我会在最后的地方通过自定义特性来进行讲解,需要看的话,可以直接拉到最下方QWQ

RangeAttribute -> 创建滑动条,将int float 的内容限制在其中


用于使脚本中的 float 或 int 变量受限于特定范围的属性。
使用此属性时,float 或 int 会在 Inspector 中显示为滑动条而不是默认数字字段。



使用特性



效果

RequireComponent -> 脚本依赖组件

RequireComponent 属性自动将所需的组件添加为依赖项。
When you add a script which uses RequireComponent to a GameObject, the required component is automatically added to the GameObject. This is useful to avoid setup errors. For example a script might require that a Rigidbody is always added to the same GameObject. When you use RequireComponent, this is done automatically, so you are unlikely to get the setup wrong.

Note: RequireComponent only checks for missing dependencies when GameObject.AddComponent is called. This happens both in the Editor, or at runtime. Unity does not automatically add any missing dependences to the components with GameObjects that lack the new dependencies.
非常有用的特性,方便,快捷



可以同时传入多个类型



只要添加这个脚本,所有可添加的类型都会被同步添加

RPC -> 用于设置 RPC 函数的属性。

用于设置 RPC 函数的属性。
根据给定的 @RPC (javascript) 或 RPC 属性 (C#),可以通过 Unity Networking 远程调用任何函数。函数必须在发送方和接收方都存在。

另请参阅:NetworkView.RPC。

RuntimeInitializeOnLoadMethodAttribute ->额外的初始化方法

允许在运行时加载游戏时不通过用户操作 初始化一个运行时类方法。
游戏加载后,将调用标记为 [RuntimeInitializeOnLoadMethod] 的 方法。这是在调用 Awake 方法后进行的。



执行脚本



执行结果

得出结论,带有这个特性的静态方法执行生命周期在Start前,Awake后,
SelectionBaseAttribute -> 改变Scene场景选取的基础对象

将此属性添加到脚本类,可将其 GameObject 标记为 Scene View 选取的选择基础对象。
在 Unity Scene View 中,当单击以选择对象时,Unity 将尝试找出为您选择的最佳对象。如果您单击作为预制件一部分的某个对象,则会选择该预制件的根,因为预制件根被视为选择基础。您也可以使其他对象被视为选择基础。您需要创建具有 SelectionBase 属性的脚本类,然后需要将该脚本添加到 GameObject。
这个特性看官方介绍个人很难理解,感觉很奇怪。
实际上,这个特性类似于一个标记,让我们快速查找到需要查找到的单位。



绑定了特性的脚本脚本



这是一个建立了一定层级的物体Cube等于场景中的方块



这个时候如果点击方块



左边的面板则会立刻锁定最下方的Cube

而我们这次将第二层的Gameobject物体上挂上脚本



带有特性的脚本挂载

重复相同的点击。



指针就不会再指向Cube而是更高层的GameObject

这个特性确实看官方描述很难理解(跟机翻一样,能理解就怪了QAQ)
SerializeField -> 强制对私有字段序列化

强制 Unity 对私有字段进行序列化。
当 Unity 对脚本进行序列化时,仅对公共字段进行序列化。 如果还需要 Unity 对私有字段进行序列化, 可以将 SerializeField 属性添加到这些字段。



正常情况下,私有的字段不会显示在Ins面板上



但是,挂载了这个特性的私有字段却被序列化了。

这样序列化的私有字段可以正常在ins面板上赋值,
(很少使用这个,如果是为了测试,为什么不先用公开后变成私有呢?反正差不多,除非后来我忘了改回私有QAQ)
SerializeReference -> 将值类型序列化为引用类型

A scripting attribute that instructs Unity to serialize a field as a reference instead of as a value.
See the serialization manual page for information about serialization and the complete serialization rules.

Without the use of the [SerializeReference] attribute, Unity serializes each of the fields of an object by value or by reference, depending on the field's type, and according to these serialization rules: UnityEngine.Object fields, by reference:
If the field type is derived from UnityEngine.Object, Unity serializes it as a reference to that object. For example, a MonoBehaviour that defines a Transform field. Fields that reference a UnityEngine.Object like this do not require the SerializeReference attribute, because the serialization for the field always records the reference to an independently-serialized object.
将字段强制序列化为引用类型,如果你的字段是String object 这类的字段,则不需要这个特性,因为它们本身就是引用类型,而如果你的字段是int, float, Vector3 这类的值类型,可以通过这个字段,将值类型变成引用类型。
____我測試過了,但是没能测试出这个特性的正确使用方式,官方案例也有些没看明白。但是这个字段确实可以正常序列化字段。
SharedBetweenAnimatorsAttribute ->

SharedBetweenAnimatorsAttribute 是一个属性,它指定此 StateMachineBehaviour 仅应实例化一次,然后供所有 Animator 实例共享。此属性可减少每个控制器实例的内存占用量。
由程序员选择哪个 StateMachineBehaviour 可使用此属性。注意,如果 StateMachineBehaviour 更改某个成员变量,则会影响使用它的其他所有 Animator 实例。 另请参阅:StateMachineBehaviour 类。
using UnityEngine;

[SharedBetweenAnimators]
public class AttackBehaviour : StateMachineBehaviour
{
    public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        Debug.Log("OnStateEnter");
    }
}官方示例
这个特性的方法基于StateMachineBehaviour类,也是动画控制器状态机组件的东西。
SpaceAttribute -> 在ins面板中添加间距

使用此 PropertyAttribute 可在 Inspector 中添加一些间距。
间距是通过 DecoratorDrawer 完成的。



使用



效果

TextAreaAttribute -> 一个更好用的可卷动字符串输入框




使用



效果

TooltipAttribute ->为字段增加悬停显示。




编程确实是一件很有趣的事情



鼠标放到字段上大约一秒钟

UnityAPICompatibilityVersionAttribute ->声明一个与特定unityApi版本兼容的程序集

声明一个与特定 Unity API 兼容(API 兼容)的程序集。内部工具用它来避免为确定程序集是否可以使用旧的 Unity API 而处理程序集。
这个东西是专门针对程序集而用的,目前个人还没有正式用过这个特性。QAQ
所以并不是很清楚这个的用法。
using System下的特性

过时特性 -- 提醒方法已经过时。

[Obsolete("过时介绍",bool)]// bool = true 则会报错, bool = false 则会警告


CallerFilePath 那个文件调用
CallerLineNumber 那一行调用
CallerMemberName那个函数调用
    public void World(string str, [CallerFilePath] string fileName = "", [CallerLineNumber] int Line = 0, [CallerMemberName] string target = "")
    {

    }这个特性可以用作异常捕获

特性终章 - 自定义特性

首先声明:特性这个东西本身并不属于Unity,它是源于C#的。
它的作用,是为元数据添加额外的信息,然后可以通过反射获取这些信息再进行处理。
创建自定义特性——需要创建一个类并继承Attribute



自定义特性的使用




特性中添加的参数实际上就是调用特性的构造方法,如果你愿意,你也可以像正常类一样,写若干个不同的构造



运行时判断是否使用了这个特性

系统会默认省略末尾的Attribute,所以下方使用时就变成了GameName




限制自定义特性的使用范围 ,使用[AttributeUsge]




相信大家都能理解

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-16 00:25 , Processed in 0.132191 second(s), 28 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表