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

news2024/12/26 20:47:05

文章目录

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

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

img

​ OdinWindow 分为两类:

  1. OdinEditorWindow

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

  2. OdinMenuEditorWindow

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

1 OdinEditorWindow

1.1 运作方式

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

img
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 中对字段、属性和方法添加特性,以实现自定义绘制效果。

img
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 对象。

img
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(),该方法用于指定窗口左侧的导航目录显示什么内容。

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,选择的对象将不会在左侧菜单栏中依据目录折叠显示。
img
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 添加导航栏示例

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;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1945363.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL的主从复制以及读写分离

主从复制 主从复制的原理&#xff1b; 读写分离&#xff0c;MHA&#xff08;高可用&#xff09;的前提是得要有主从复制 主从复制的模式&#xff1a; 1、MySQL的默认模式&#xff1a; 异步模式 住主库在更新完事务之后会立即把结果返回给从服务器&#xff0c;并不关心从库…

Github 2024-07-17 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-07-17统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量非开发语言项目3Python项目3Rust项目2TypeScript项目2MDX项目1项目化学习 创建周期:2538 天协议类型:MIT LicenseStar数量:161973 个Fork数量…

Unity UGUI 之 Slider

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 1.Slider是什么 滑块&#xff0c;由三部分组成&#xff1a;背景 填充条 手柄 填充条就是…

提升网站性能:ThinkPHP6中如何实现Mysql分页查询

随着互联网的快速发展&#xff0c;web应用程序的开发也越来越复杂。而分页查询是web应用程序中常见的功能之一。thinkphp6是一个web框架&#xff0c;可以帮助开发人员快速开发应用程序。在本文中&#xff0c;我们将讨论如何在thinkphp6中使用mysql进行分页查询。 首先&#xf…

【java计算机毕设】医用物理学实验考核系统java MySQL ssm JSP maven项目设计源码+文档 寒暑假作业

目录 1项目功能 2项目介绍 3项目地址 1项目功能 【java计算机毕设】医用物理学实验考核系统java MySQL ssm JSP maven项目设计源码文档 寒暑假作业 2项目介绍 系统功能&#xff1a; 医用物理学实验考核系统包括管理员、学生、教师三种角色。 管理员功能包括个人中心模块用于…

Google Cloud Platform数据工程简介

Google Cloud Platform数据工程简介 前言 云计算的出现为数据驱动型组织提供了采用成本效益高且可扩展的数据工程解决方案的机会。在云服务提供商中&#xff0c;Google Cloud Platform (GCP) 是近年来表现优异的领导者之一。GCP的增长被归因于其在企业和初创公司中的日益普及…

【Leetcode】十八、动态规划:不同路径 + 最大正方形

文章目录 1、动态规划2、leetcode509&#xff1a;斐波那契数列3、leetcode62&#xff1a;不同路径4、leetcode121&#xff1a;买卖股票的最佳时机5、leetcode70&#xff1a;爬楼梯6、leetcode279&#xff1a;完全平方数7、leetcode221&#xff1a;最大正方形 1、动态规划 只能…

SAP库龄计算报表(源码)

一个简单的库龄计算报表&#xff0c;根据移动类型来判断最后移动日期&#xff0c;包含批次和非批次库存。 *&---------------------------------------------------------------------* *& Report ZMMR_016 *&---------------------------------------------------…

数据代理实践

1&#xff0c;什么事数据代理机制&#xff1f; 通过访问 代理对象的属性 来向该访问 目标对象的属性 数据代理机制的视线需要依靠&#xff0c;Object.defineProperty()方法 2&#xff0c; ES6新特性&#xff1a; 在对象中的函数/方法 &#xff1a;function是可以省略的 &l…

P2-AI产品经理-九五小庞

项目要怎么做 需求&#xff0c;技术&#xff0c;构建流程&#xff0c;算法 要懂&#xff0c;懂什么&#xff1f; 懂产品方案&#xff0c;包含&#xff1a; 不懂&#xff0c;会遇到哪些问题&#xff1f; 跟算法供应商沟通的专业度不足&#xff0c;容易被边缘化&#xff0c;…

手写数字识别(机器学习)

一&#xff1a;一对多分类方法(one-vs-all) 这里先上的代码&#xff0c;想看原理可以到代码下面。 在数据集中&#xff0c;y的取值为1~10&#xff0c;y10表示当前数字为0 首先读取数据,并对数据进行切分。 import pandas as pd import numpy as np import matplotlibmatplo…

美摄科技企业级视频拍摄与编辑SDK解决方案

在数字化浪潮汹涌的今天&#xff0c;视频已成为企业传递信息、塑造品牌、连接用户不可或缺的强大媒介。为了帮助企业轻松驾驭这一视觉盛宴的制作过程&#xff0c;美摄科技凭借其在影视级非编技术领域的深厚积累&#xff0c;推出了面向企业的专业视频拍摄与编辑SDK解决方案&…

Linux磁盘扩容lvm

目录 Linux磁盘管理基础知识介绍 1.确认分区类型 2.添加新硬盘 3.给新硬盘添加分区 &#xff08;2&#xff09;指定分区类型 4.创建物理卷 5.创建卷组 6.扩展逻辑卷 7.刷新文件系统 &#xff08;1&#xff09;查看文件系统 xfs文件系统使用&#xff08;centos&#…

RocketMQ集群搭建,看完这篇文章你就懂了(基于2m-2s-async模式)

前言 上一篇初步认识了RocketMQ&#xff0c;这一篇文章我们简单来搭建一个RocketMQ集群。RocketMQ支持多种集群部署模式&#xff0c;其中最常用的是多主多从的异步复制模式&#xff08;2m代表两个master&#xff0c;2s代表两个slave&#xff0c;async代表异步刷盘的机制&#…

数据结构 - AVL树

文章目录 一、AVL树的介绍二、AVL树的实现1、基本框架2、查找3、插入4、删除5、测试6、总代码 三、AVL树的性能 一、AVL树的介绍 1、概念 AVL树&#xff08;Adelson-Velsky and Landis Tree&#xff09;是一种自平衡的二叉搜索树。它得名于其发明者G. M. Adelson-Velsky和E. M…

广东工程职业技术学院财经学院领导一行莅临泰迪智能科技参观交流

7月19日&#xff0c;广东工程职业技术学院财经学院市场调查与统计分析专业主任苏志鹏、专业老师余乐莅临广东泰迪智能科技股份有限公司产教融合实训基地参观交流。泰迪智能科技董事长张良均、副总经理施兴、高校业务部经理孙学镂、校企合作经理吴桂锋进行接待。 仪式伊始&#…

保持形态真实性的大脑生成建模| 文献速递-基于人工智能(AI base)的医学影像研究与疾病诊断

Title 题目 Realistic morphology-preserving generative modelling of the brain 保持形态真实性的大脑生成建模 01 文献速递介绍 医学影像研究通常受到数据稀缺和可用性的限制。治理、隐私问题和获取成本都限制了医学影像数据的访问&#xff0c;加上深度学习算法对数据的…

苍穹外卖(一)之环境搭建篇

Ngnix启动一闪而退 启动之前需要确保ngnix.exe的目录中没有中文字体&#xff0c;在conf目录下的nginx.conf文件查看ngnix的端口号&#xff0c;一般默认为80&#xff0c;若80端口被占用就会出现闪退现象。我们可以通过logs/error.log查看错误信息&#xff0c;错误信息如下&…

k8s+containerd(kvm版)

k8s&#xff08;Kubernetes&#xff09;是由Gogle开源的容器编排引擎&#xff0c;可以用来管理容器化的应用程序和服务&#xff0c;k 高可用&#xff1a;系统在长时间内持续正常地运行&#xff0c;并不会因为某一个组件或者服务的故障而导致整个系统不可用可扩展性&#xff1a…

freesql简单使用操作mysql数据库

参考&#xff1a;freesql中文官网指南 | FreeSql 官方文档 这两天准备做一个测试程序&#xff0c;往一个系统的数据表插入一批模拟设备数据&#xff0c;然后还要模拟设备终端发送数据包&#xff0c;看看系统的承压能力。 因为系统使用的第三方框架中用到了freesql&#xff0c…