Unity插件——Odin 学习笔记(一)

工具研究 专栏收录该内容
17 篇文章 2 订阅

本文章是为了记录学习Unity插件Odin,使用该插件可以让我们更快速便捷的开发Unity工具

前言

Unity原生编辑编辑器的方法有两种——IMGUI和新的UIElement
1.UIElement我之前做过介绍,开发模式类似于HTML+CSS,如果有类似经验的人开发及相对容易,但是就目前而言不太适合编辑器开发,我觉得比较适合取代UGUI进行UI开发
2.IMGUI入门比较简单,使用EditorGUILayout或者GUILayout来编写编辑器并进行排版和布局,通过回调来添加事件,但是写多了,EditorGUILayout会变得层层叠叠,代码可读性变得非常差,没有合理的注释或者拆分的话,可能时间一长自己都看不懂了
3.Odin就是基于IMGUI的编辑器拓展的插件,同时也可以帮助开发者进行序列化操作(Unity原生的序列化不支持很多类型,Odin支持比Unity更多的序列化,例如二维数组、Dictionary),在使用Odin的时候,我们通过Odin中给予我们的Attributes来快速影响我们所需要编辑的字段,帮助我们快速开发可视化界面以及工具

案例:Attributes Overview

1. Basic Editor Changes

1.1. Default Drawer Changes

1.1.1. InfoBox

使用[InfoBox]可以在编辑器中添加提示框

  • string Message——信息
  • InfoMessageType InfoMessageType——信息类型(Info/Warning/Error),会改变图标类型
  • string VisibleIf——是否显示,需要填入函数名,返回值为bool类型,根据返回值决定是否显示提示框
  • bool GUIAlwaysEnabled——是否无视GUI.enable显示
[InfoBox("All enums will now have a more feature-rich dropdown that introduces search.",InfoMessageType = InfoMessageType.Warning,VisibleIf = "ChangeShow")]
public KeyCode NormalEnum;
public bool ChangeShow()
{
	return NormalEnum == KeyCode.A ? true : false;//只有当NormalEnum为KeyCode.A时才会显示提示框
}

1.1.2. 普通属性

例如int,Vector2,Rect等,还是和原来一样

1.1.3. Title

使用[Title]可以在编辑器中添加标题

  • string Title——标题
  • string Subtitle——副标题
  • bool Bold——是否加粗
  • bool HorizontalLine——有否有水平线分割(如下图)
  • TitleAlignments TitleAlignment——标题对齐方式(Left/Centered/Right/Split),前三个为左中右,标题与副标题上下排列,最后一个标题左对齐,副标题右对齐(如下图)
[Title("Small Facts",Subtitle ="aaa",TitleAlignment = TitleAlignments.Split, Bold = true, HorizontalLine = true)]

在这里插入图片描述


1.2. Lists

1.2.1. List< T >

List< T >类型的可视化界面如下图所示
在这里插入图片描述

1.2.2. Range

使用[Range]可以将数值变成滑动条的形式,如果使用在数组上,数组都会变成滑动条
在这里插入图片描述

1.2.3. ListDrawerSettings

使用[ListDrawerSettings]可以对List类型的UI进行定制

  • bool HideAddButton——是否隐藏Add按钮,隐藏上图所示“+”按钮
  • bool AddCopiesLastElement——是否在Add时复制最后一个元素
  • string OnEndListElementGUI——在List每个元素更新前需要调用的函数
  • string OnBeginListElementGUI——在List每个元素更新后需要调用的函数
  • string CustomRemoveElementFunction——在点击移除键时调用的函数,根据元素值
  • bool AlwaysAddDefaultValue——(没弄懂)理论上是在点击时不会显示其派生类供选择,直接显示基类T
  • string CustomAddFunction——自定义Add按钮的函数,返回值为元素
  • string ListElementLabelName——List中元素的标签名,参数为字段/属性名
  • bool HideRemoveButton——是否隐藏移除按钮
  • string CustomRemoveIndexFunction——在点击移除键时调用的函数,根据元素的index值
[System.Serializable]
public class A
{
    public float num;
}

[System.Serializable]
public class AB : A
{
    public int i;
}

[System.Serializable]
public class AC : A
{
    public bool j;
}
//超级简单的案例
[InfoBox("Applying a [Range] attribute to this list instead applies it to all of its float entries.")]
//[Range(0, 1)]
[ListDrawerSettings(HideAddButton = false,CustomRemoveElementFunction = "CustomRemove", AddCopiesLastElement = true,
OnBeginListElementGUI = "BeginGUI",OnEndListElementGUI ="EndGUI",AlwaysAddDefaultValue = false, 
CustomAddFunction = "AddElement",ListElementLabelName = "num")]
public List<A> FloatRangeArray;

private void BeginGUI(int index)
{
	Debug.Log("BeginGUI" + index);
}
private void EndGUI(int index)
{
	Debug.Log("EndGUI" + index);
}
private string LabelName()
{
    return "Element";
}
private void CustomRemove(A value)
{
    Debug.Log("CustomRemove" + value.num);
    FloatRangeArray.Remove(value);
}
private A AddElement()
{
    return new A();
}

  • string OnTitleBarGUI——在TitleBar上绘制按钮
  • bool DraggableItems——是否可拖动
  • bool Expanded——是否展开,默认为合上
  • bool ShowItemCount——是否显示物品个数
  • bool IsReadOnly——是否只读
  • int NumberOfItemsPerPage——每页物品数量,默认为15
  • bool ShowPaging——是否分页,默认为分页,每页超过NumberOfItemsPerPage就会自动分页
  • bool ShowIndexLabels——是否显示该元素为第几个
[InfoBox("Applying a [Range] attribute to this list instead applies it to all of its float entries.")]
//[Range(0, 1)]
[ListDrawerSettings(OnTitleBarGUI = "DrawResetButton", DraggableItems = false,
Expanded = true,NumberOfItemsPerPage = 5,ShowPaging = true)]
public List<A> FloatRangeArray;

private void DrawResetButton()
{
    if (SirenixEditorGUI.ToolbarButton(EditorIcons.Refresh))
    {
        for (int i = 0; i < FloatRangeArray.Count; i++)
        {
            FloatRangeArray[i].num = i;
        }
    }
}

private void TitleBar()
{
    Debug.Log("TitleBar");
}

1.2.4. ReadOnly

  • 使用[ReadOnly]会变灰,无法更改
    在这里插入图片描述

  • 注意: 使用[ListDrawerSettings(IsReadOnly = true)]和[ReadOnly]作用相同,看上去略有不同在这里插入图片描述


2. Type Specific Attributes

2.1. Enum Toggle Buttons

首先要声明Enum类型,有两种方式:第一种方式只能单选,第二种方式能多选

public enum SomeEnum
{
    First, Second, Third, Fourth, AndSoOn
}

[System.Flags]
public enum SomeBitmaskEnum
{
    A = 1 << 1,
    B = 1 << 2,
    C = 1 << 3,
    All = A | B | C
}

2.1.1. 默认枚举

  • 单选
    在这里插入图片描述
  • 多选
    在这里插入图片描述

2.1.2. EnumToggleButtons

使用[EnumToggleButtons]标签可以以按钮的形式显示枚举类型
根据枚举的声明方式变成单选或多选
在这里插入图片描述

2.1.3. HideLabel

使用[HideLabel]可以隐藏标签栏,如上图所示


2.2. Enum Paging

2.2.1. EnumPaging

对于单选的枚举类型可以使用[EnumPaging],多了两个切换的箭头
在这里插入图片描述

2.2.2. OnValueChanged()

使用OnValueChanged(“函数名”),可以在数值变化的时候调用函数

[EnumPaging, OnValueChanged("SetCurrentTool")]
[InfoBox("Example of using EnumPaging together with OnValueChanged.")]
public UnityEditor.Tool SceneTool;

private void SetCurrentTool()
{
    UnityEditor.Tools.current = this.SceneTool;
}
  • string MethodName——函数名
  • bool IncludeChildren——是否对子节点也调用

2.3. Min Max Slider

2.3.1. MinMaxSlider

使用[MinMaxSlider]可以对Vector2设置最大最小值

  • float MinValue——最小值
  • float MaxValue——最大值
  • string MinMember——通过字段/函数设置最小值
  • string MaxMember——通过字段/函数设置最大值
  • string MinMaxMember——通过字段/函数设置最大最小值
  • bool ShowFields——是否显示范围,会显示数值
[InfoBox("You can also assign the min max values dynamically by refering to members.")]
[MinMaxSlider("DynamicRange", true)]
public Vector2 DynamicMinMax;//最大最小值通过DynamicRange控制

[MinMaxSlider("Min", 10f, true)]
public Vector2 DynamicMin;//最小值通过DynamicRange.x控制

[MinMaxSlider(0f, "Max", true)]
public Vector2 DynamicMax;//最大值通过DynamicRange.y控制

public Vector2 DynamicRange;

public float Min()
{
    return this.DynamicRange.x;
}
//public float Min { get { return this.DynamicRange.x; } }

public float Max { get { return this.DynamicRange.y; } }

在这里插入图片描述


2.4. Min and Max Value

下面两者可以同时使用限制值的范围

2.4.1. MinValue

使用[MinValue]可以限制当前值的最小值

2.4.2. MaxValue

使用[MaxValue]可以限制当前值的最大值


2.5. Preview Fields for Unity Objects

2.5.1. PreviewField

使用[PreviewField]用来显示Object类型

  • float Height——Object显示的高度
  • ObjectFieldAlignment Alignment——对齐方式(Left/Centered/Right)
    在这里插入图片描述

注意:

  • 可以拖动Object进行移动和交换
  • 按住Ctrl键点击可以删除
  • 按住Ctrl键进行拖动可以复制

2.6. Wrap Values

2.6.1. Wrap

使用[Wrap]可以让变量在最大和最小值之间重复,例如[Wrap(0,100)],超过100之后就会回到0继续增加,反之亦然
不仅对于int、float等类型有效,对Vector3之类的类型也有效

  • double Min——最小值
  • double Max——最大值

2.7. Color Palettes

2.7.1. 默认调色板

在Edit/Preferences/Odin Inspector/Show Odin Preferences/Color Palettes中可以找到Odin中的调色板选项,其中已经有了一些默认的调色板,同时也可以自行添加调色板,方法很简单,这里不多赘述

2.7.2. ColorPalette

使用[ColorPalette]可以使用预制的调色板来选取颜色

  • string PaletteName——调色板名
  • bool ShowAlpha——是否显示Alpha值(在默认调色板界面设置)
[ColorPalette("Underwater")]
public Color UnderwaterColor;

public string DynamicPaletteName = "Clovers";
[ColorPalette("$DynamicPaletteName")]
public Color DynamicPaletteColor;

[ColorPalette("Clovers")]
public Color[] ColorArray;

因此,我们可以使用ColorPalette来指定颜色需要什么样的调色板,也可以通过设置string变量来输入想要的调色板,对颜色数组使用的话,那么数组中的颜色都可以通过调色板进行设置
在这里插入图片描述


2.8. Asset List

2.8.1. AssetList

通过[AssetList]可以显示文件夹中的符合条件的asset

  • bool AutoPopulate——自动添加数据,当数据被找到了之后,会自动添加
  • string Tags——筛选符合Tags的assets
  • string LayerNames——筛选符合Layers的assets
  • string AssetNamePrefix——筛选名字以所需string开头的assets
  • string Path——资源路径,为“Assets”+"/**/"
  • string CustomFilterMethod——筛选符合函数条件的assets

2.9. Inline Editor

2.9.1. DisableInInlineEditors

使用[DisableInInlineEditors]的属性在[InlineEditors]中禁用

2.9.2. HideInInlineEditors

使用[HideInInlineEditors]的属性在[InlineEditors]中隐藏

2.9.3. InlineEditor

使用[InlineEditor]可以显示继承自UnityEngine.Object的对象的数据

  • bool Expanded——是否默认展开
  • bool DrawHeader——是否绘制Header,也就是最上面一块
    在这里插入图片描述
  • bool DrawGUI——是否绘制GUI,不绘制就都没有了
  • bool DrawPreview——是否绘制缩略图
  • float MaxHeight——最大高度,超过最大值会有滚动条
  • float PreviewWidth——缩略图的宽度
  • float PreviewHeight——缩略图的高度
  • InlineEditorObjectFieldModes ObjectFieldMode——Object的显示模式
    1.Boxed——盒子显示,默认
    2.Foldout——下拉框显示
    3.Hidden——除非Object为Null否则隐藏
    4.CompletelyHidden——完全隐藏
  • InlineEditorModes inlineEditorMode——显示模式
    1.GUIOnly——只显示GUI
    2.GUIAndHeader——显示GUI和标题
    3.GUIAndPreview——显示GUI和缩略图
    4.SmallPreview——显示小缩略图
    5.LargePreview——显示大缩略图
    6.FullEditor——全部显示

2.10. Progress Bar Examples

2.10.1. ProgressBar

使用[ProgressBar]可以制作花哨的进度条

  • double Min——最大值
  • double Max——最小值
  • string MinMember——通过函数/属性设置最小值
  • string MaxMember——通过函数/属性设置最大值
  • int Height——高度
  • string CustomValueStringMember——通过函数/属性设置显示的文字
  • string BackgroundColorMember——通过函数/属性设置背景颜色
  • bool Segmented——变成一格一格
    在这里插入图片描述
  • string ColorMember——通过函数/属性设置颜色
  • float R——颜色R
  • float G——颜色G
  • float B——颜色B

通过这个我们可以制作出更加多样的进度条
在这里插入图片描述


2.11. Folder and File Paths

2.11.1. FolderPath

使用[FolderPath]可以选择文件夹然后得到string,在默认状态下打开的是相对Unity绝对路径的路径

  • bool AbsolutePath——得到绝对路径
  • string ParentFolder——会得到相对所给父路径的路径
  • bool RequireExistingPath——需要存在路径,否则会报错
  • bool UseBackslashes——是否使用反斜杠

2.11.2. FilePath

[FilePath]的使用方法与[FolderPath]相同,参数只多了一项

  • string Extensions——仅能看到特定拓展名的文件
// FilePath also supports member references with the $ symbol.
[FilePath(ParentFolder = "$DynamicParent", Extensions = "$DynamicExtensions")]
[BoxGroup("Member referencing")]
public string DynamicFilePath;

[BoxGroup("Member referencing")]
public string DynamicParent = "Assets/Plugin/Sirenix";

[BoxGroup("Member referencing")]
public string DynamicExtensions = "cs, unity, jpg";

在这里插入图片描述


2.12. Value Dropdowns

2.12.1. ValueDropdown

使用[ValueDropdown]可以在下拉框中显示值

  • string MemberName——所需的值字段的名字,继承自IEnumerable
  • bool SortDropdownItems——是否排序
  • string DropdownTitle——下拉框标题
  • int DropdownHeight——下拉框宽度
  • int DropdownWidth——下拉框高度
  • bool FlattenTreeView——默认为树状
  • bool DoubleClickToConfirm——是否双击确认
  • bool HideChildProperties——是否隐藏子属性
  • bool DisableGUIInAppendedDrawer——是否能在Inspector面板进行操作
  • bool ExpandAllMenuItems——是否全部展开
  • bool ExcludeExistingValuesInList——是否在添加时忽略已添加的值
  • bool DisableListAddButtonBehaviour——是否禁用Add键
  • bool DrawDropdownForListElements——是否绘制子类中的下拉框
  • bool IsUniqueList——List中的值是否都唯一
  • int NumberOfItemsBeforeEnablingSearch——达到多少值可以进行搜索
  • bool AppendNextDrawer——是否分离下拉框,下拉框在左边,显示在右边
    在这里插入图片描述

下面是IEnumerable的使用案例

private static IEnumerable FriendlyTextureSizes = new ValueDropdownList<int>()
{
    { "Small", 256 },
    { "Medium", 512 },
    { "Large", 1024 },
};

private static int[] TextureSizes = new int[] { 256, 512, 1024 };

private IEnumerable TreeViewOfInts = new ValueDropdownList<int>()
{
    { "Node 1/Node 1.1", 1 },
    { "Node 1/Node 1.2", 2 },
    { "Node 2/Node 2.1", 3 },
    { "Node 3/Node 3.1", 4 },
    { "Node 3/Node 3.2", 5 },
    { "Node 1/Node 3.1/Node 3.1.1", 6 },
    { "Node 1/Node 3.1/Node 3.1.2", 7 },
};

private static IEnumerable GetAllScriptableObjects()
{
    return UnityEditor.AssetDatabase.FindAssets("t:ScriptableObject")
        .Select(x => UnityEditor.AssetDatabase.GUIDToAssetPath(x))
        .Select(x => new ValueDropdownItem(x, UnityEditor.AssetDatabase.LoadAssetAtPath<ScriptableObject>(x)));
}

2.13. Toggle Left

2.13.1. ToggleLeft

使用[ToggleLeft]可以决定是否绘制有标签的属性

2.13.2. EnableIf

[EnableIf]中参数为[ToggleLeft]的名字,根据[ToggleLeft]决定是否启用
在这里插入图片描述


2.14. MultiLine Property

2.14.1. MultiLineProperty

使用[MultiLineProperty]来生成多行文本框,Odin的MultiLineProperty支持字段和属性,而Unity只支持字段

  • int Lines——多行文本框有几行
  • 12
    点赞
  • 0
    评论
  • 39
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值