2024-07-16 Unity插件 Odin Inspector6 —— Group Attributes

1 说明

​ 本文介绍 Odin Inspector 插件中有关 Group 特性的使用方法。

2 Group 特性

2.1 BoxGroup

绘制按钮组。

  • string group

    按钮组名称。

  • bool showLabel = true

    是否显示标题。

  • bool centerLabel = false

    标题是否居中。

  • float order = 0.0f

    按钮组的排序。

image-20240716034040374
// BoxGroupExamplesComponent.cs

using Sirenix.OdinInspector;
using System;
using UnityEngine;

public class BoxGroupExamplesComponent : MonoBehaviour
{
    // Box with a title.
    [BoxGroup("Some Title")]
    public string A;

    [BoxGroup("Some Title")]
    public string B;

    // Box with a centered title.
    [BoxGroup("Centered Title", centerLabel: true)]
    public string C;

    [BoxGroup("Centered Title")]
    public string D;

    // Box with a title received from a field.
    [BoxGroup("$G")]
    public string E = "Dynamic box title 2";

    [BoxGroup("$G")]
    public string F;

    // No title
    [BoxGroup]
    public string G;

    [BoxGroup]
    public string H;

    // A named box group without a title.
    [BoxGroup("NoTitle", false)]
    public string I;

    [BoxGroup("NoTitle")]
    public string J;

    [BoxGroup("A Struct In A Box"), HideLabel]
    public SomeStruct BoxedStruct;

    public SomeStruct DefaultStruct;

    [Serializable]
    public struct SomeStruct
    {
        public int One;
        public int Two;
        public int Three;
    }
}

2.2 ButtonGroup

将 Button 分组显示。

  • string group = "_DefaultGroup"

    组名。

  • float order = 0.0f

    顺序。

  • int ButtonHeight

    按钮组中所有按钮的高度。

image-20240715003708316
// ButtonGroupExamplesComponent.cs

using System;
using Sirenix.OdinInspector;
using UnityEngine;

public class ButtonGroupExamplesComponent : MonoBehaviour
{
    public IconButtonGroupExamples iconButtonGroupExamples;

    [ButtonGroup]
    private void A() { }

    [ButtonGroup]
    private void B() { }

    [ButtonGroup]
    private void C() { }

    [ButtonGroup]
    private void D() { }

    [Button(ButtonSizes.Large)]
    [ButtonGroup("My Button Group")]
    private void E() { }

    [GUIColor(0, 1, 0)]
    [ButtonGroup("My Button Group")]
    private void F() { }

    [Serializable, HideLabel]
    public struct IconButtonGroupExamples
    {
        [ButtonGroup(ButtonHeight = 25), Button(SdfIconType.ArrowsMove, "")]
        void ArrowsMove() { }

        [ButtonGroup, Button(SdfIconType.Crop, "")]
        void Crop() { }

        [ButtonGroup, Button(SdfIconType.TextLeft, "")]
        void TextLeft() { }

        [ButtonGroup, Button(SdfIconType.TextRight, "")]
        void TextRight() { }

        [ButtonGroup, Button(SdfIconType.TextParagraph, "")]
        void TextParagraph() { }

        [ButtonGroup, Button(SdfIconType.Textarea, "")]
        void Textarea() { }
    }
}

​ 可以与 TitleGroup 组合使用。

image-20240715003758748
// BigTitleGroupExampleComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;

public class BigTitleGroupExampleComponent : MonoBehaviour
{
    [BoxGroup("Titles", ShowLabel = false)]
    [TitleGroup("Titles/First Title")]
    public int A;
    
    [BoxGroup("Titles/Boxed")]
    [TitleGroup("Titles/Boxed/Second Title")]
    public int B;
    
    [TitleGroup("Titles/Boxed/Second Title")]
    public int C;
    
    [TitleGroup("Titles/Horizontal Buttons")]
    [ButtonGroup("Titles/Horizontal Buttons/Buttons")]
    public void FirstButton() { }
    
    [ButtonGroup("Titles/Horizontal Buttons/Buttons")]
    public void SecondButton() { }
}

2.3 FoldoutGroup

将对象添加到折叠组。

  • string groupName

    折叠组名称。

  • bool expanded

    是否默认展开。

  • float order = 0.0f

    折叠组的排序。

image-20240716034608539
// FoldoutGroupAttributeExamplesComponent.cs

using Sirenix.OdinInspector;
using UnityEngine;

public class FoldoutGroupAttributeExamplesComponent : MonoBehaviour
{
    [FoldoutGroup("Group 1")]
    public int A;

    [FoldoutGroup("Group 1")]
    public int B;

    [FoldoutGroup("Group 1")]
    public int C;

    [FoldoutGroup("Collapsed group", expanded: false)]
    public int D;

    [FoldoutGroup("Collapsed group")]
    public int E;

    [FoldoutGroup("$GroupTitle", expanded: true)]
    public int One;

    [FoldoutGroup("$GroupTitle")]
    public int Two;

    public string GroupTitle = "Dynamic group title";
}

2.4 ShowIfGroup / HideIfGroup

满足某个条件,则显示 / 隐藏指定组。

  • string path

    指定组的路径。

  • object value

    与路径末尾标签重名的属性等于该值时,则满足条件。

  • bool animate = true

    状态改变时是否启用滑入和滑出动画显示。

image-20240716000503730
// HideIfGroupExampleComponent.cs

using Sirenix.OdinInspector;
using UnityEngine;

public class HideIfGroupExampleComponent : MonoBehaviour
{
    public bool Toggle = true;

    [HideIfGroup("Toggle")]
    [BoxGroup("Toggle/Shown Box")]
    public int A, B;

    [BoxGroup("Box")]
    public InfoMessageType EnumField = InfoMessageType.Info;

    [BoxGroup("Box")]
    [HideIfGroup("Box/Toggle")]
    public Vector3 X, Y;

    // Like the regular If-attributes, HideIfGroup also supports specifying values.
    // You can also chain multiple HideIfGroup attributes together for more complex behaviour.
    [HideIfGroup("Box/Toggle/EnumField", Value = InfoMessageType.Info)]
    [BoxGroup("Box/Toggle/EnumField/Border", ShowLabel = false)]
    public string Name;

    [BoxGroup("Box/Toggle/EnumField/Border")]
    public Vector3 Vector;

    // HideIfGroup will by default use the name of the group,
    // but you can also use the MemberName property to override this.
    [HideIfGroup("RectGroup", Condition = "Toggle")]
    public Rect Rect;
}

2.5 HorizontalGroup

将对象添加到水平组。

  • float width = 0.0f

    水平宽度。

  • int marginLeft/marginRight = 0

    左/右侧边距(单位:像素)。

  • int PaddingLeft/PaddingRight = 0

    左右填充。

    值介于 0 和 1 之间的值将被视为百分比;值为 0 则表示忽略;大于 1 的整数被视为像素。

  • float order = 0.0f

    水平组的排序。

  • float Gap = 3f

    每列之间的宽度。

    值介于 0 和 1 之间的值将被视为百分比;否则为像素。

  • string Title

    水平组的标题名称。

image-20240716035140890
// HorizontalGroupAttributeExamplesComponent.cs

using System;
using Sirenix.OdinInspector;
using UnityEngine;

public class HorizontalGroupAttributeExamplesComponent : MonoBehaviour
{
    // The width can either be specified as percentage or pixels.
    // All values between 0 and 1 will be treated as a percentage.
    // If the width is 0 the column will be automatically sized.

    // Auto width
    [HorizontalGroup]
    public SomeFieldType Left1;

    [HorizontalGroup]
    public SomeFieldType Right1;

    // Margins
    [HorizontalGroup("row2", MarginRight = 0.4f)]
    public SomeFieldType Left2;

    [HorizontalGroup("row2")]
    public SomeFieldType Right2;


    // Custom width:
    [HorizontalGroup("row1", Width = 0.25f)] // 25 %
    public SomeFieldType Left3;

    [HorizontalGroup("row1", Width = 150)] // 150 px
    public SomeFieldType Center3;

    [HorizontalGroup("row1")] // Auto / expand
    public SomeFieldType Right3;


    // Gap Size
    [HorizontalGroup("row3", Gap = 3)]
    public SomeFieldType Left4;

    [HorizontalGroup("row3")]
    public SomeFieldType Center4;

    [HorizontalGroup("row3")] // Auto / expand
    public SomeFieldType Right4;


    // Title
    [HorizontalGroup("row4", Title = "Horizontal Group Title")]
    public SomeFieldType Left5;

    [HorizontalGroup("row4")]
    public SomeFieldType Center5;

    [HorizontalGroup("row4")]
    public SomeFieldType Right5;

    [HideLabel, Serializable]
    public struct SomeFieldType
    {
        [LabelText("@$property.Parent.NiceName")]
        [ListDrawerSettings(ShowIndexLabels = true)]
        public float[] x;
    }
}

2.6 ResponsiveButtonGroup

将按钮绘制在组内,该组将响应其可用的水平空间。

  • string group = "_DefaultResponsiveButtonGroup"

    组名。

image-20240715004200320
// ResponsiveButtonGroupExampleComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;

#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.OdinInspector.Editor.Examples;
#endif

public class ResponsiveButtonGroupExampleComponent : MonoBehaviour
{
#if UNITY_EDITOR // Editor-related code must be excluded from builds
    [Button(ButtonSizes.Large), GUIColor(0, 1, 0)]
    private void OpenDockableWindowExample()
    {
        var window = UnityEditor.EditorWindow.GetWindow<MyDockableGameDashboard>();
        window.WindowPadding = new Vector4();
    }
#endif
    
    [OnInspectorGUI] private void Space1() { GUILayout.Space(20); }
    
    [ResponsiveButtonGroup] public void Foo() { }
    [ResponsiveButtonGroup] public void Bar() { }
    [ResponsiveButtonGroup] public void Baz() { }
    
    [OnInspectorGUI] private void Space2() { GUILayout.Space(20); }
    
    [ResponsiveButtonGroup("UniformGroup", UniformLayout = true)] public void Foo1() { }
    [ResponsiveButtonGroup("UniformGroup")] public void Foo2() { }
    [ResponsiveButtonGroup("UniformGroup")] public void LongesNameWins() { }
    [ResponsiveButtonGroup("UniformGroup")] public void Foo4() { }
    [ResponsiveButtonGroup("UniformGroup")] public void Foo5() { }
    [ResponsiveButtonGroup("UniformGroup")] public void Foo6() { }
    
    [OnInspectorGUI] private void Space3() { GUILayout.Space(20); }
    
    [ResponsiveButtonGroup("DefaultButtonSize", DefaultButtonSize = ButtonSizes.Small)] public void Bar1() { }
    [ResponsiveButtonGroup("DefaultButtonSize")] public void Bar2() { }
    [ResponsiveButtonGroup("DefaultButtonSize")] public void Bar3() { }
    [Button(ButtonSizes.Large), ResponsiveButtonGroup("DefaultButtonSize")] public void Bar4() { }
    [Button(ButtonSizes.Large), ResponsiveButtonGroup("DefaultButtonSize")] public void Bar5() { }
    [ResponsiveButtonGroup("DefaultButtonSize")] public void Bar6() { }
    
    [OnInspectorGUI] private void Space4() { GUILayout.Space(20); }
    
    [FoldoutGroup("SomeOtherGroup")]
    [ResponsiveButtonGroup("SomeOtherGroup/SomeBtnGroup")] public void Baz1() { }
    [ResponsiveButtonGroup("SomeOtherGroup/SomeBtnGroup")] public void Baz2() { }
    [ResponsiveButtonGroup("SomeOtherGroup/SomeBtnGroup")] public void Baz3() { }
}

​ 与 TabGroup 结合使用:

image-20240715004248291
// BigTabGroupExampleComponent.cs

using Sirenix.OdinInspector;
using UnityEngine;

public class BigTabGroupExampleComponent : MonoBehaviour
{
    [TitleGroup("Tabs")]
    [HorizontalGroup("Tabs/Split", Width = 0.5f)]
    [TabGroup("Tabs/Split/Parameters", "A")]
    public string NameA, NameB, NameC;

    [TabGroup("Tabs/Split/Parameters", "B")]
    public int ValueA, ValueB, ValueC;

    [TabGroup("Tabs/Split/Buttons", "Responsive")]
    [ResponsiveButtonGroup("Tabs/Split/Buttons/Responsive/ResponsiveButtons")]
    public void Hello() { }

    [ResponsiveButtonGroup("Tabs/Split/Buttons/Responsive/ResponsiveButtons")]
    public void World() { }

    [ResponsiveButtonGroup("Tabs/Split/Buttons/Responsive/ResponsiveButtons")]
    public void And() { }

    [ResponsiveButtonGroup("Tabs/Split/Buttons/Responsive/ResponsiveButtons")]
    public void Such() { }

    [Button]
    [TabGroup("Tabs/Split/Buttons", "More Tabs")]
    [TabGroup("Tabs/Split/Buttons/More Tabs/SubTabGroup", "A")]
    public void SubButtonA() { }

    [Button]
    [TabGroup("Tabs/Split/Buttons/More Tabs/SubTabGroup", "A")]
    public void SubButtonB() { }

    [Button(ButtonSizes.Gigantic)]
    [TabGroup("Tabs/Split/Buttons/More Tabs/SubTabGroup", "B")]
    public void SubButtonC() { }
}

2.7 TabGroup

将对象添加到选项卡组中。

  • string group

    组名。不指定组名,则添加到默认组中。

  • string tab

    选项卡。

  • SdfIconType icon

    图标。

  • bool useFixedHeight = false

    设置为 true,使整个选项卡组的高度保持恒定。

  • float order = 0.0f

    选项卡组的显示顺序(从小到大)。

  • string TextColor

    字体颜色。支持多种颜色格式。

    1. 命名颜色。如 “red”, “orange”, “green”, “blue”。
    2. 十六进制代码。如 “#FF0000”、“#FF0000FF”。
    3. RGBA。如 “RGBA(1,1,1,1)”。
    4. RGB。如 “RGB(1,1,1)”。
  • string TabName

    Inspector 窗口中显示的选项卡名称。

  • TabLayouting TabLayouting

    选项卡布局。

image-20240716040053425
// TabGroupExamplesComponent.cs

using Sirenix.OdinInspector;
using System;
using UnityEngine;

public class TabGroupExamplesComponent : MonoBehaviour
{
    [TabGroup("General")]
    public string playerName1;

    [TabGroup("General")]
    public int playerLevel1;

    [TabGroup("General")]
    public string playerClass1;

    [TabGroup("Stats")]
    public int strength1;

    [TabGroup("Stats")]
    public int dexterity1;

    [TabGroup("Stats")]
    public int intelligence1;

    [TabGroup("Quests")]
    public bool hasMainQuest1;

    [TabGroup("Quests")]
    public int mainQuestProgress1;

    [TabGroup("Quests")]
    public bool hasSideQuest1;

    [TabGroup("Quests")]
    public int sideQuestProgress1;


    [TabGroup("tab2", "General", SdfIconType.ImageAlt, TextColor = "green")]
    public string playerName2;

    [TabGroup("tab2", "General")]
    public int playerLevel2;

    [TabGroup("tab2", "General")]
    public string playerClass2;

    [TabGroup("tab2", "Stats", SdfIconType.BarChartLineFill, TextColor = "blue")]
    public int strength2;

    [TabGroup("tab2", "Stats")]
    public int dexterity2;

    [TabGroup("tab2", "Stats")]
    public int intelligence2;

    [TabGroup("tab2", "Quests", SdfIconType.Question, TextColor = "@questColor", TabName = "")]
    public bool hasMainQuest2;

    [TabGroup("tab2", "Quests")]
    public Color questColor = new Color(1, 0.5f, 0);

    [TabGroup("shrink tabs", "World Map", SdfIconType.Map, TextColor = "orange", TabLayouting = TabLayouting.Shrink)]
    [TabGroup("shrink tabs", "Character", SdfIconType.PersonFill, TextColor = "orange")]
    [TabGroup("shrink tabs", "Wand", SdfIconType.Magic, TextColor = "red")]
    [TabGroup("shrink tabs", "Abilities", TextColor = "green")]
    [TabGroup("shrink tabs", "Missions", SdfIconType.ExclamationSquareFill, TextColor = "yellow")]
    [TabGroup("shrink tabs", "Collection 1", TextColor = "blue")]
    [TabGroup("shrink tabs", "Collection 2", TextColor = "blue")]
    [TabGroup("shrink tabs", "Collection 3", TextColor = "blue")]
    [TabGroup("shrink tabs", "Collection 4", TextColor = "blue")]
    [TabGroup("shrink tabs", "Settings", SdfIconType.GearFill, TextColor = "grey")]
    [TabGroup("shrink tabs", "Guide", SdfIconType.QuestionSquareFill, TextColor = "blue")]
    public float a, b, c, d;

    [TabGroup("multi row", "World Map", SdfIconType.Map, TextColor = "orange", TabLayouting = TabLayouting.MultiRow)]
    [TabGroup("multi row", "Character", SdfIconType.PersonFill, TextColor = "orange")]
    [TabGroup("multi row", "Wand", SdfIconType.Magic, TextColor = "red")]
    [TabGroup("multi row", "Abilities", TextColor = "green")]
    [TabGroup("multi row", "Missions", SdfIconType.ExclamationSquareFill, TextColor = "yellow")]
    [TabGroup("multi row", "Collection 1", TextColor = "blue")]
    [TabGroup("multi row", "Collection 2", TextColor = "blue")]
    [TabGroup("multi row", "Collection 3", TextColor = "blue")]
    [TabGroup("multi row", "Collection 4", TextColor = "blue")]
    [TabGroup("multi row", "Settings", SdfIconType.GearFill, TextColor = "grey")]
    [TabGroup("multi row", "Guide", SdfIconType.QuestionSquareFill, TextColor = "blue")]
    public float e, f, g, h;

    [Serializable]
    [HideLabel]
    public class MyTabObject
    {
        public int A;
        public int B;
        public int C;
    }
}

2.8 ToggleGroup

将对象添加进单选框组。

  • string toggleMemberName

    启用或禁用 ToggleGroup 的任何 bool 字段或属性的名称。

  • float order = 0.0f

    单选框组的排序。

  • string groupTitle = null

    Inspector 窗口中显示的标题名称。

image-20240716043131827
// ToggleGroupExamplesComponent.cs

using Sirenix.OdinInspector;
using System;
using UnityEngine;

public class ToggleGroupExamplesComponent : MonoBehaviour
{
    // Simple Toggle Group
    [ToggleGroup("MyToggle")]
    public bool MyToggle;

    [ToggleGroup("MyToggle")]
    public float A;

    [ToggleGroup("MyToggle")]
    [HideLabel, Multiline]
    public string B;

    // Toggle for custom data.
    [ToggleGroup("EnableGroupOne", "$GroupOneTitle")]
    public bool EnableGroupOne = true;

    [ToggleGroup("EnableGroupOne")]
    public string GroupOneTitle = "One";

    [ToggleGroup("EnableGroupOne")]
    public float GroupOneA;

    [ToggleGroup("EnableGroupOne")]
    public float GroupOneB;

    // Toggle for individual objects.
    [Toggle("Enabled")]
    public MyToggleObject Three = new MyToggleObject();

    [Toggle("Enabled")]
    public MyToggleA Four = new MyToggleA();

    [Toggle("Enabled")]
    public MyToggleB Five = new MyToggleB();

    public MyToggleC[] ToggleList = new MyToggleC[] {
        new MyToggleC() { Test = 2f, Enabled = true, },
        new MyToggleC() { Test = 5f, },
        new MyToggleC() { Test = 7f, },
    };

    [Serializable]
    public class MyToggleObject
    {
        public bool Enabled;

        [HideInInspector]
        public string Title;

        public int A;
        public int B;
    }

    [Serializable]
    public class MyToggleA : MyToggleObject
    {
        public float C;
        public float D;
        public float F;
    }

    [Serializable]
    public class MyToggleB : MyToggleObject
    {
        public string Text;
    }

    [Serializable]
    public class MyToggleC
    {
        [ToggleGroup("Enabled", "$Label")]
        public bool Enabled;

        public string Label { get { return this.Test.ToString(); } }

        [ToggleGroup("Enabled")]
        public float Test;
    }
}

2.9 VerticalGroup

将对象添加到垂直组。

  • string groupId

    垂直组 ID。

  • float order = 0.0f

    垂直组的排序。

  • float PaddingTop/PaddingBottom

    上下填充(单位:像素)。

image-20240716044058307
// VerticalGroupExamplesComponent.cs

using Sirenix.OdinInspector;
using UnityEngine;

public class VerticalGroupExamplesComponent : MonoBehaviour
{
    [HorizontalGroup("Split")]
    [VerticalGroup("Split/Left")]
    public InfoMessageType First;

    [VerticalGroup("Split/Left")]
    public InfoMessageType Second;

    [HideLabel]
    [VerticalGroup("Split/Right")]
    public int A;

    [HideLabel]
    [VerticalGroup("Split/Right")]
    public int B;
}

相关推荐

  1. 2024-07-19 Unity Odin Serializer1 —— 介绍

    2024-07-17 12:20:02       20 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 12:20:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 12:20:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 12:20:02       58 阅读
  4. Python语言-面向对象

    2024-07-17 12:20:02       69 阅读

热门阅读

  1. android.app.application can not be cast to android.app.Activity

    2024-07-17 12:20:02       21 阅读
  2. 优化Conda环境:深入掌握conda clean命令的清理艺术

    2024-07-17 12:20:02       22 阅读
  3. 探索Conda的搜索能力:挖掘Python包的宝藏

    2024-07-17 12:20:02       27 阅读
  4. conda 环境打包与使用

    2024-07-17 12:20:02       29 阅读
  5. C语言——练习:将数组中的n个元素按逆序存放

    2024-07-17 12:20:02       23 阅读
  6. django form 将表单数据发送到后端触发弹窗

    2024-07-17 12:20:02       30 阅读
  7. 什么样的服务器是合乎直销网站标准

    2024-07-17 12:20:02       18 阅读
  8. FinClip 中如何使用小程序插件?

    2024-07-17 12:20:02       24 阅读
  9. Fastgpt本地或服务器私有化部署常见问题

    2024-07-17 12:20:02       24 阅读
  10. 跟ChatGPT学习go语言-float64转成int

    2024-07-17 12:20:02       22 阅读
  11. Redis--布隆过滤器

    2024-07-17 12:20:02       22 阅读
  12. geometry_msgs

    2024-07-17 12:20:02       23 阅读