2024-07-23 Unity插件 Odin Inspector11 —— 使用 Odin 自定义编辑窗口

文章目录

  • [1 OdinEditorWindow](#1 OdinEditorWindow)
    • [1.1 运作方式](#1.1 运作方式)
    • [1.2 使用特性绘制 OdinEditorWindow](#1.2 使用特性绘制 OdinEditorWindow)
    • [1.3 在 OdinEditorWindow 中渲染对象](#1.3 在 OdinEditorWindow 中渲染对象)
  • [2 OdinMenuEditorWindow](#2 OdinMenuEditorWindow)
    • [2.1 添加菜单导航栏](#2.1 添加菜单导航栏)
    • [2.2 添加导航栏示例](#2.2 添加导航栏示例)

Odin Window 可以完整地访问 Odin 绘图系统,不再需要操心 Window 的绘制 方式 ,而是专注于真正重要的事情:Window 提供的功能。

​ OdinWindow 分为两类:

  1. OdinEditorWindow

    用法与 Inspector 中使用特性自定义属性显示方式类似。

  2. OdinMenuEditorWindow

    能够创建具有左侧导航目录的窗口。本教程着重讲解如何创建 OdinMenuEditorWindow。

1 OdinEditorWindow

1.1 运作方式

​ 只需继承 OdinEditorWindow 类,而不是 EditorWindow ,就可以像使用 Odin Inspector 一样,在窗口中呈现字段、属性和方法,而无需编写任何自定义编辑器 GUI 代码。

csharp 复制代码
public class MyCustomEditorWindow : OdinEditorWindow
{
    [MenuItem("My Game/My Editor")]
    private static void OpenWindow() {
        GetWindow<MyCustomEditorWindow>().Show();
    }

    public string Hello;
}

1.2 使用特性绘制 OdinEditorWindow

​ 和 MonoBehaviour 或 ScriptableObject 一样,在 OdinEditorWindow 中对字段、属性和方法添加特性,以实现自定义绘制效果。

csharp 复制代码
public class MyCustomEditorWindow : OdinEditorWindow
{
    [MenuItem("My Game/My Editor")]
    private static void OpenWindow() {
        GetWindow<MyCustomEditorWindow>().Show();
    }

    [EnumToggleButtons, BoxGroup("Settings")]
    public ScaleMode ScaleMode;

    [FolderPath(RequireExistingPath = true), BoxGroup("Settings")]
    public string OutputPath;

    [HorizontalGroup(0.5f)]
    public List&lt;Texture&gt; InputTextures;

    [HorizontalGroup, InlineEditor(InlineEditorModes.LargePreview)]
    public Texture Preview;

    [Button(ButtonSizes.Gigantic), GUIColor(0, 1, 0)]
    public void PerformSomeAction() { }
}

1.3 在 OdinEditorWindow 中渲染对象

​ 重写 GetTarget() 方法,并为其提供任何类型的任何实例进行呈现。它不需要可序列化,甚至不需要是 Unity 对象。

csharp 复制代码
public class MyCustomEditorWindow : OdinEditorWindow
{
    [MenuItem("My Game/My Editor")]
    private static void OpenWindow() {
        GetWindow<MyCustomEditorWindow>().Show();
    }

    protected override void Initialize() {
        this.WindowPadding = Vector4.zero;
    }

    protected override object GetTarget() {
        return Selection.activeObject;
    }
}

2 OdinMenuEditorWindow

2.1 添加菜单导航栏

​ 继承 OdinMenuEditorWindow 类后,需要实现其抽象方法:BuildMenuTree(),该方法用于指定窗口左侧的导航目录显示什么内容。

csharp 复制代码
using Sirenix.OdinInspector.Editor;

public class EnemyDataEditor : OdinMenuEditorWindow
{
    protected override OdinMenuTree BuildMenuTree() {
        throw new System.NotImplementedException();
    }
}

​ 添加导航目录的方法通常有 2 种:

  1. OdinMenuTree.Add(string path, object instance)

    直接在导航目录中绘制某个对象。

    • path:导航栏名称。
    • instance:右侧绘制的对象。
  2. OdinMenuTree.AddAllAssetsAtPath( string menuPath, string assetFolderPath, Type type, bool includeSubDirectories = false, bool flattenSubDirectories = false)

    在导航目录中绘制某个目录下所有类型为 type 的对象。

    • menuPath:导航栏名称。
    • assetFolderPath:选择的目录。
    • type:对象类型。
    • includeSubDirectories:是否在子目录中也寻找对象。
    • flattenSubDirectories:如果为 true,选择的对象将不会在左侧菜单栏中依据目录折叠显示。
csharp 复制代码
public class MyCustomEditorWindow : OdinMenuEditorWindow
{
    [MenuItem("My Game/My Editor")]
    private static void OpenWindow() {
        GetWindow<MyCustomEditorWindow>().Show();
    }

    protected override OdinMenuTree BuildMenuTree() {
        var tree = new OdinMenuTree();
        tree.Selection.SupportsMultiSelect = false;

        // 方法 1
        tree.Add("Settings", GeneralDrawerConfig.Instance); 
        tree.Add("Utilities", new TextureUtilityEditor());
        
        // 方法 2
        tree.AddAllAssetsAtPath("Odin Settings", "Assets/Plugins/Sirenix", typeof(ScriptableObject), true, true);
        
        return tree;
    }
}

public class TextureUtilityEditor
{
    [BoxGroup("Tool"), HideLabel, EnumToggleButtons]
    public Tool Tool;

    public List&lt;Texture&gt; Textures;

    [Button(ButtonSizes.Large), HideIf("Tool", Tool.Rotate)]
    public void SomeAction() { }

    [Button(ButtonSizes.Large), ShowIf("Tool", Tool.Rotate)]
    public void SomeOtherAction() { }
}

2.2 添加导航栏示例

csharp 复制代码
public class MyCustomEditorWindow : OdinMenuEditorWindow
{
    [MenuItem("My Game/My Editor")]
    private static void OpenWindow() {
        GetWindow<MyCustomEditorWindow>().Show();
    }

    protected override OdinMenuTree BuildMenuTree() {
        var tree = new OdinMenuTree();
        tree.Selection.SupportsMultiSelect = false;

        OdinMenuTree tree = new OdinMenuTree(supportsMultiSelect: true) {
            { "Home", this, EditorIcons.House },
            { "Odin Settings", null, SdfIconType.GearFill },
            { "Odin Settings/ Color Palettes", ColorPaletteManager.Instance, EditorIcons.EyeDropper  },
            { "Odin Settings/ AOT Generation", AOTGenerationConfig.Instance, EditorIcons.SmartPhone  },
            { "Camera current", Camera.current },
            { "Some Class", this.someData }
        };

        tree.AddAllAssetsAtPath("Some Menu Item", "Some Asset Path", typeof(ScriptableObject), true)
            .AddThumbnailIcons();

        tree.AddAssetAtPath("Some Second Menu Item", "SomeAssetPath/ SomeAssetFile. asset");

        var customMenuItem = new OdinMenuItem(tree, "Menu Style", tree.DefaultMenuStyle);
        tree.MenuItems.Insert(2, customMenuItem);

        tree.Add("Menu/ Items/ Are/ Created/ As/ Needed", new GUIContent());
        tree.Add("Menu/ Items/ Are/ Created", new GUIContent("And can be overridden"));
        
        return tree;
    }
}
相关推荐
自由的好好干活12 小时前
使用Qoder编写ztdaq的C#跨平台示例总结
linux·windows·c#·qoder
FuckPatience13 小时前
C# 实现元素索引由1开始的链表
开发语言·链表·c#
avi911114 小时前
发现一个宝藏Unity开源AVG框架,视觉小说的脚手架
unity·开源·框架·插件·tolua·avg
我是唐青枫17 小时前
C#.NET 范围与索引(Range、Index)完全解析:语法、用法与最佳实践
c#·.net
烛阴19 小时前
从`new()`到`.DoSomething()`:一篇讲透C#方法与构造函数的终极指南
前端·c#
深海潜水员20 小时前
【MonoGame游戏开发】| 牧场物语实现 第一卷 : 农场基础实现 (下)
vscode·游戏·c#·.net·monogame
合作小小程序员小小店20 小时前
图书管理系统,基于winform+sql sever,开发语言c#,数据库mysql
开发语言·数据库·sql·microsoft·c#
一线灵1 天前
跨平台游戏引擎 Axmol-2.10.0 发布
游戏引擎
大侠课堂1 天前
C#经典面试题100道
开发语言·c#
时光追逐者1 天前
Visual Studio 2026 现已正式发布,更快、更智能!
ide·c#·.net·visual studio