Unity编辑器扩展之Attribute特性(三)

内容将会持续更新,有错误的地方欢迎指正,谢谢!
 

Unity编辑器扩展之Attribute特性(三)
     
TechX 坚持将创新的科技带给世界!

拥有更好的学习体验 —— 不断努力,不断进步,不断探索
TechX —— 心探索、心进取!

助力快速掌握 Attribute 编辑器扩展

为初学者节省宝贵的学习时间,避免困惑!

Unity编辑器扩展之Attribute特性(一)

Unity编辑器扩展之Attribute特性(二)

Unity编辑器扩展之Attribute特性(三)

Unity编辑器扩展之Attribute特性(四)


前言:

  Unity 特性是一种用于装饰(标记)类、字段、方法和属性的 .NET 特性,用于控制 Unity 引擎的行为、检查代码的有效性以及提供更多的编辑器功能。Unity 特性可以帮助开发者更好地定制和控制游戏对象、组件、编辑器界面和其他 Unity 相关元素的行为。

在这里插入图片描述



一、CustomEditort

CustomEditor 用于关联自定义编辑器脚本类与特定的游戏对象脚本类。

这使得你可以为游戏对象脚本类创建自定义检视器面板,以便更灵活地编辑游戏对象的属性。

通常情况下,Unity会根据游戏对象的脚本自动生成一个默认的检视器面板。但有时,你可能需要更多的控制权,以按照自己的方式自定义检视器面板。这就是 CustomEditor 特性派上用场的地方。

以下是一个使用 CustomEditor 特性的示例:

using UnityEngine;

public class MyComponent : MonoBehaviour
{
    
    
    public float age;
    public string myName;
}
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor : Editor
{
    
    
    private MyComponent myComponent {
    
     get {
    
     return (MyComponent)target; } }

    public override void OnInspectorGUI()
    {
    
    
        myComponent.age= EditorGUILayout.FloatField("年龄", myComponent.age);
        myComponent.myName = EditorGUILayout.TextField("名字", myComponent.myName);
    }
}

在这个示例中,我们创建了一个名为 MyComponentEditor 的自定义编辑器类,并将其与 MyComponent脚本关联。

通过 CustomEditor特性,我们告诉 Unity 编辑器,当你在检视器面板中选择一个拥有 MyComponent脚本的游戏对象时,应该使用 MyComponentEditor 类来绘制其检视器面板。

MyComponentEditor 类继承自 Editor 类,重写了 OnInspectorGUI 方法,以便可以自定义检视器的外观和行为。在这个方法中,你可以创建自定义的GUI元素,例如按钮、滑动条、文本字段等,以编辑游戏对象脚本的属性。

在这里插入图片描述



二、CanEditMultipleObjects

CanEditMultipleObjects 用于标记自定义编辑器脚本类,允许你同时编辑多个相同类型的对象。

这对于在 Unity 编辑器中处理多个对象的编辑非常有用。

当你创建一个自定义编辑器脚本(通常是继承自 Editor 类),你可以使用 CanEditMultipleObjects 特性来指示你的编辑器可以同时编辑多个对象。

这意味着当你选择多个相同类型的对象时,Unity 会使用你的自定义编辑器来显示它们的属性,并让你可以一次性修改它们的值。

以下是一个 CanEditMultipleObjects特性的示例:

using UnityEditor;

[CustomEditor(typeof(MyComponent))]
[CanEditMultipleObjects]
public class MyComponentEditor : Editor
{
    
    
    private MyComponent myComponent {
    
     get {
    
     return (MyComponent)target; } }

    public override void OnInspectorGUI()
    {
    
    
        base.OnInspectorGUI();

        myComponent.age= EditorGUILayout.FloatField("年龄值", myComponent.age);
        myComponent.myName = EditorGUILayout.TextField("名字", myComponent.myName);

    }
}

在上面的示例中,我们创建了一个名为 MyComponentEditor 的自定义编辑器,并为它的目标对象类型添加了 CustomEditor特性,以及 CanEditMultipleObjects特性。这表示当你选择多个 MyComponent 类型的对象时,Unity 会使用 MyComponentEditor 来编辑它们。

这个特性非常适用于处理一组具有相同脚本类型的对象,允许你一次性修改它们的属性,提高了编辑效率。

在这里插入图片描述



三、CustomPreviewAttribute

CustomPreviewAttribute 允许你为特定类型的资源或组件提供自定义预览功能。资源文件包括纹理、声音、模型等。

这样,你可以在 Inspector 中查看资源或组件时,显示自定义的预览图像,而不仅仅是默认的图标。

通过使用 CustomPreviewAttribute特性,你可以为特定类型的资源文件创建自定义的预览面板,使其在资源窗口中显示自定义信息和视觉元素。

以下是一个 CustomPreviewAttribute特性的示例:

[CustomPreview(typeof(Texture))] // 将预览特性与 Texture 关联
public class TexturePreview : ObjectPreview
{
    
    
    public override bool HasPreviewGUI()
    {
    
    
        return true;
    }
    public override GUIContent GetPreviewTitle()
    {
    
    
        return new GUIContent("Custom Texture Preview");
    }

    public override void OnPreviewGUI(Rect r, GUIStyle background)
    {
    
    
        if (target is Texture)
        {
    
    
            Texture texture = (Texture)target;
            // 绘制纹理预览
             GUI.DrawTexture(new Rect(r.width / 4, r.height / 4, r.width/2,r.height/2), texture);
            // 在预览面板上绘制内容
             GUI.Label(new Rect(r.width / 4, r.height / 2, r.width / 2, r.height / 2), 
             "Custom Preview Example", new GUIStyle {
    
    
             	fontSize = 40,
             	normal = {
    
     textColor=Color.white} 
             } );
        }
    }

这个示例创建了一个名为 TexturePreview 的自定义预览面板。它与 Texture 类型的资源文件关联,然后重写了三个方法:

HasPreviewGUI方法定义了什么状态下需要显示预览窗口。

GetPreviewTitle 方法返回了预览面板的标题。

OnPreviewGUI 方法用于绘制自定义的预览内容,这里我们绘制了 Texture2D 类型资源的纹理。

在这里插入图片描述



四、DrawGizmo

DrawGizmo 特性用于在 Scene 视图中绘制 Gizmos,这是 Unity 编辑器中用于可视化调试和编辑的图形表示。

开发者可以使用 DrawGizmo 特性自定义如何在 Scene 视图中绘制这些 Gizmos。

该特性可以用于自定义编辑器类,以便在编辑场景中的对象时,你可以显示自定义的 Gizmos,以帮助可视化场景中的各种信息。

下面是 DrawGizmo 的基本用法示例:

using UnityEngine;

public class MyScript : MonoBehaviour
{
    
    
}
using UnityEngine;
using UnityEditor;

public class MyScriptGizmoDrawer
{
    
    
    [DrawGizmo(GizmoType.Selected | GizmoType.Active)]
    static void DrawGizmoForMyScript(MyScript scr, GizmoType gizmoType)
    {
    
    
        // 在选中或激活状态下绘制 Gizmo
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(scr.transform.position, 1.0f);
    }
}

在上面的示例中,MyScriptGizmoDrawer类包含了一个静态方法 DrawGizmoForMyScript,它使用 DrawGizmo 特性。这个特性指示 Unity 在选中或激活对象的状态下绘制 Gizmo。在这个示例中,我们绘制了一个红色的线框球体 Gizmo,其位置由对象的变换 transform 决定。

在这里插入图片描述



五、ExecuteAlways

ExecuteAlways 特性用于标记在 Unity 中的脚本类,以确保它们在编辑模式和播放模式下都会执行。这对于那些需要在编辑器中及运行时持续运行的脚本非常有用。

使用 ExecuteAlways 特性,你可以实时预览脚本的效果,而无需进入播放模式。这对于视觉效果的微调和交互式开发非常有用。

ExecuteAlways 特性通常用于编辑器下执行需要实时预览效果的操作。这包括自定义编辑器工具、Gizmos、特效等。开发者可以在编辑器下即时看到结果,而不必每次都进入播放模式。

下面是 ExecuteAlways 的基本用法示例:

[ExecuteAlways]
public class MyComponent : MonoBehaviour
{
    
    
    void Start()
    {
    
    
        if (Application.IsPlaying(gameObject))
        {
    
    
            Debug.Log("Play logic");
        }
        else
        {
    
    
            Debug.Log("Editor logic");
        }
    }
}

在上面的示例中,MyComponent 类被标记为 ExecuteAlways 特性。

这表示其中的 Start()方法将在编辑器模式和播放模式下都执行。

我们可以使用Application.IsPlaying()方法来判断是执行编辑器模式的逻辑和播放模式的逻辑。



六、ExecuteInEditMode

ExecuteInEditMode 特性用于标记在 Unity 中的脚本类,以确保它们在编辑模式下也会执行,而不仅仅在播放模式下执行。这对于那些需要在编辑器中进行实时交互和编辑的脚本非常有用。

下面是 ExecuteInEditMode 的基本用法示例:

using UnityEngine;

[ExecuteInEditMode] // 使用 ExecuteInEditMode 特性
public class EditModeScript : MonoBehaviour
{
    
    
    public Vector3 somePosition;

    private void Update()
    {
    
    
        // 这里的代码将在编辑器模式下执行
        transform.position = somePosition;
    }
}

在上面的示例中,EditModeScript 类被标记为 ExecuteInEditMode 特性。这表示其中的 Update 方法将在编辑器模式下也执行。这允许开发者在编辑场景时实时观察和交互对象的属性,而不必进入播放模式。



七、EditorWindowTitleAttribute

EditorWindowTitleAttribute 用于自定义编辑器窗口的标题。它允许开发者为自定义编辑器窗口指定一个特定的标题,以提高编辑器窗口的可读性和识别性。

通常,在自定义编辑器窗口的脚本类中,你可以使用 EditorWindowTitleAttribute 特性来为窗口指定一个标题。

下面是 EditorWindowTitleAttribute 的基本用法示例:

[EditorWindowTitle(title = "My Custom Window")] // 使用 EditorWindowTitle 特性
public class MyCustomWindow : EditorWindow
{
    
    
    [MenuItem("Window/MyWindow")]//在unity菜单Window下有MyWindow选项
    static void Init()
    {
    
    
        MyCustomWindow myWindow = GetWindow<MyCustomWindow>();
        myWindow.Show();//展示
    }
}

在上面的示例中,MyCustomWindow 类被标记为 EditorWindowTitleAttribute 特性,标题设置为 “My Custom Window”。当你打开或激活这个自定义编辑器窗口时,窗口的标题将显示为 “My Custom Window”。

在这里插入图片描述



八、InitializeOnEnterPlayModeAttribute

InitializeOnEnterPlayModeAttribute 特性是 Unity 中的一个编辑器脚本特性,用于标记在进入播放模式时需要初始化的方法。

当你需要在切换到播放模式前执行特定的初始化操作,可以使用这个特性。

下面是 InitializeOnEnterPlayModeAttribute 的基本用法示例:

using UnityEditor;
using UnityEngine;

public class MyInitializer
{
    
    
    [InitializeOnEnterPlayMode] // 使用 InitializeOnEnterPlayMode 特性
    public static void InitializeOnPlayMode()
    {
    
    
        Debug.Log("Entered Play Mode, initializing...");
        // 在进入播放模式时执行的初始化操作
    }
}


在上面的示例中,InitializeOnEnterPlayModeAttribute 特性被用于标记一个静态方法 InitializeOnPlayMode。

这个方法将在切换到播放模式前执行初始化操作。通常,你可以在这个方法中执行必要的设置或重置,以确保游戏在播放模式下以预期的方式运行。

这个特性对于需要在进入播放模式时重置某些状态或执行其他初始化操作的情况非常有用。例如,你可以用它来初始化游戏关卡、重置关卡计时器或加载必要的资源。



九、InitializeOnLoadAttribute

InitializeOnLoadAttribute 用于在 Unity 加载时和重新编译脚本时初始化 Editor 类。

重新编译项目中的脚本时,会调用带有此属性的静态构造函数(也称为域重新加载)。

在 Unity 首次加载项目时、在 Unity 检测到脚本修改时(取决于自动刷新首选项),以及当进入运行模式时(取决于运行模式配置),会进行此调用。

以下是 InitializeOnLoadAttribute 的基本用法示例:

using UnityEditor;
using UnityEngine;

[InitializeOnLoad]
public class MyInitialization
{
    
    
    static MyInitialization()
    {
    
    
        // 在指定的时刻执行初始化代码
        Debug.Log("Initialization has occurred.");
    }
}

在上面的示例中,InitializeOnLoadAttribute 被用于标记一个静态构造函数。

这个构造函数将在 Unity 编辑器启动时执行,以进行自定义的初始化操作。

使用 InitializeOnLoadAttribute 的典型情况包括注册自定义编辑器工具、设置编辑器菜单项、加载资源或执行其他需要在编辑器启动时运行的任务。



十、InitializeOnLoadMethodAttribute

InitializeOnLoadMethodAttribute 用于在 Unity 加载时和重新编译脚本时初始化方法。

重新编译项目中的脚本时,会调用带有此属性的静态方法。

在 Unity 首次加载项目时、在 Unity 检测到脚本修改时,以及当进入运行模式时,会进行此调用。

以下是 InitializeOnLoadMethodAttribute 的基本用法示例:

using UnityEditor;

public class MyInitialization
{
    
    
    [InitializeOnLoadMethod]
    static void Initialize()
    {
    
    
        // 在指定的时刻执行初始化代码
        Debug.Log("Initialization method has been called.");
    }
}

在上面的示例中,InitializeOnLoadMethodAttribute 被用于标记一个静态方法 Initialize。这个方法将在 Unity 加载时和重新编译脚本时执行,以进行自定义的初始化操作。



十一、SettingsProviderAttribute

SettingsProviderAttribute 用于标记静态方法以提供自定义设置界面。这个特性通常用于创建自定义的设置面板,以便用户可以轻松配置你的工具或扩展。

以下是 SettingsProviderAttribute 的基本用法示例:

public static class MySettingsProvider
{
    
    
    [SettingsProvider]
    public static SettingsProvider CreateMyCustomSettingsProvider()
    {
    
    
        var provider = new SettingsProvider("MyTool/CustomSettings", SettingsScope.User)
        {
    
    
            label = "Custom Settings",
            guiHandler = (searchContext) =>
            {
    
    
                // 在此处绘制自定义设置界面
                EditorGUILayout.LabelField("This is a custom settings page.");
            },
            keywords = new HashSet<string>(new[] {
    
     "Custom", "Settings" }),
        };
        return provider;
    }
}

在这个示例中,我们使用 SettingsProviderAttribute 标记了名为 CreateMyCustomSettingsProvider 的静态方法。这个方法返回一个 SettingsProvider 对象,定义了自定义设置页面的属性和行为,包括页面的名称、GUI 绘制方法和搜索关键字。

在 SettingsProvider 中,你可以设置以下属性:

label:设置设置页面的名称。

guiHandler:指定在设置页面中绘制 GUI 元素的方法。你可以在这里创建你的自定义设置界面。

keywords:指定设置页面的搜索关键字,以便用户可以更容易地找到它。

一旦你定义了 SettingsProvider,用户就可以在 Unity 编辑器的设置中找到你的自定义设置页面。这对于创建工具、插件或扩展的用户配置界面非常有用。用户可以在这里调整你的工具的各种参数和选项。

在这里插入图片描述



十二、SelectionBaseAttribute

SelectionBaseAttribute 用于将其 GameObject 标记为 Scene View 选取的选择基础对象。

在 Unity Scene View 中,当单击以选择对象时,Unity 将尝试找出为您选择的最佳对象。

如果单击作为预制件一部分的某个对象,则会选择该预制件的根,因为预制件根被视为选择基础。
也可以使其他对象被视为选择基础。

需要创建具有 SelectionBase 属性的脚本类,然后需要将该脚本添加到 GameObject。

[SelectionBase] // 使用 SelectionBase 特性
public class MyComponent : MonoBehaviour
{
    
    
}




TechX —— 心探索、心进取!

每一次跌倒都是一次成长

每一次努力都是一次进步

END
感谢您阅读本篇博客!希望这篇内容对您有所帮助。如果您有任何问题或意见,或者想要了解更多关于本主题的信息,欢迎在评论区留言与我交流。我会非常乐意与大家讨论和分享更多有趣的内容。
如果您喜欢本博客,请点赞和分享给更多的朋友,让更多人受益。同时,您也可以关注我的博客,以便及时获取最新的更新和文章。
在未来的写作中,我将继续努力,分享更多有趣、实用的内容。再次感谢大家的支持和鼓励,期待与您在下一篇博客再见!

猜你喜欢

转载自blog.csdn.net/caiprogram123/article/details/133955477