欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > 2024-07-18 Unity插件 Odin Inspector8 —— Type Specific Attributes

2024-07-18 Unity插件 Odin Inspector8 —— Type Specific Attributes

2024/10/25 21:57:57 来源:https://blog.csdn.net/zheliku/article/details/140510399  浏览:    关键词:2024-07-18 Unity插件 Odin Inspector8 —— Type Specific Attributes

文章目录

  • 1 说明
  • 2 特定类型特性
    • 2.1 AssetList
    • 2.2 AssetSelector
    • 2.3 ChildGameObjectsOnly
    • 2.4 ColorPalette
    • 2.5 DisplayAsString
    • 2.6 EnumPaging
    • 2.7 EnumToggleButtons
    • 2.8 FilePath
    • 2.9 FolderPath
    • 2.10 HideInInlineEditors
    • 2.11 HideInTables
    • 2.12 HideMonoScript
    • 2.13 HideReferenceObjectPicker
    • 2.14 InlineEditor
    • 2.15 Multiline
    • 2.16 PreviewField
    • 2.17 PolymorphicDrawerSettings
    • 2.18 TypeDrawerSettings
    • 2.19 SceneObjectsOnly
    • 2.20 TableList
    • 2.21 TableMatrix
    • 2.22 Toggle
    • 2.23 ToggleGroup

1 说明

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

2 特定类型特性

2.1 AssetList

用于 List、Array 和单个对象,将默认导航选择窗口替换为可筛选的 Asset 列表,以筛选、包含或排除 List、Array 中的 Asset。

  • string Path

    筛选 Asset 列表,仅包括位于指定路径的 Asset。

  • bool AutoPopulate

    如果为 true ,则将 Asset 列表中找到并显示的所有资产自动添加到列表中。

  • string LayerNames

    筛选 Asset 列表,使其仅包含具有指定 Layer 的资源。

  • string AssetNamePrefix

    筛选 Asset 列表,使其仅包含名称以开头的 Asset。

  • string Tags

    标签列表(以逗号分隔),用于筛选 Asset 列表。

  • string CustomFilterMethod

    筛选 Asset 列表,使其仅包含给定筛选方法返回 true 的 Asset。

image-20240718015148658
// AssetListExamplesComponent.csusing Sirenix.OdinInspector;
using System.Collections.Generic;
using UnityEngine;public class AssetListExamplesComponent : MonoBehaviour
{[AssetList][PreviewField(70, ObjectFieldAlignment.Center)]public Texture2D SingleObject;[AssetList(Path = "/Plugins/Sirenix/")]public List<ScriptableObject> AssetList;[FoldoutGroup("Filtered Odin ScriptableObjects", expanded: false)][AssetList(Path = "Plugins/Sirenix/")]public ScriptableObject Object;[AssetList(AutoPopulate = true, Path = "Plugins/Sirenix/")][FoldoutGroup("Filtered Odin ScriptableObjects", expanded: false)]public List<ScriptableObject> AutoPopulatedWhenInspected;[AssetList(LayerNames = "MyLayerName")][FoldoutGroup("Filtered AssetLists examples")]public GameObject[] AllPrefabsWithLayerName;[AssetList(AssetNamePrefix = "Rock")][FoldoutGroup("Filtered AssetLists examples")]public List<GameObject> PrefabsStartingWithRock;[FoldoutGroup("Filtered AssetLists examples")][AssetList(Tags = "MyTagA, MyTabB", Path = "/Plugins/Sirenix/")]public List<GameObject> GameObjectsWithTag;[FoldoutGroup("Filtered AssetLists examples")][AssetList(CustomFilterMethod = "HasRigidbodyComponent")]public List<GameObject> MyRigidbodyPrefabs;private bool HasRigidbodyComponent(GameObject obj) {return obj.GetComponent<Rigidbody>() != null;}
}

2.2 AssetSelector

可用于所有 Unity 类型,在对象字段旁边添加小按钮。单击该按钮将显示资产下拉列表以供选择,可从该属性中进行自定义。

  • bool FlattenTreeView

    下拉列表是否树状显示。

  • string Paths

    指定搜索的文件夹。不指定任何文件夹则在整个项目中搜索(使用“|”作为分隔符表示多条路径)。

  • string Filter

    调用 AssetDatabase.FindAssets 时使用的过滤器。

  • bool DisableListAddButtonBehaviour = false

    禁用列表添加按钮行为。

  • bool DrawDropdownForListElements = true

    当 ValueDropdown 特性应用于该对象时,则禁用 DrawDropdownForListElements 将正常呈现所有子元素。

  • bool ExcludeExistingValuesInList

    当 ValueDropdown 特性应用于该对象时,并且 IsUniqueList 为 true,则启用 ExcludeExistingValuesInList 时,排除现有值,而不是显示一个复选框,指示该项是否已包含在内。

  • bool IsUniqueList = true

    子元素是否唯一。

  • bool ExpandAllMenuItems = true

    如果下拉菜单呈现树视图,则将其设置为 true 时,默认情况下所有内容都会被展开显示。

  • string DropdownTitle

    自定义下拉列表标题。

image-20240718020158603
// AssetSelectorExamplesComponent.csusing Sirenix.OdinInspector;
using System.Collections.Generic;
using UnityEngine;public class AssetSelectorExamplesComponent : MonoBehaviour
{[AssetSelector]public Material AnyAllMaterials;[AssetSelector]public Material[] ListOfAllMaterials;[AssetSelector(FlattenTreeView = true)]public Material NoTreeView;[AssetSelector(Paths = "Assets/MyScriptableObjects")]public ScriptableObject ScriptableObjectsFromFolder;[AssetSelector(Paths = "Assets/MyScriptableObjects|Assets/Other/MyScriptableObjects")]public Material ScriptableObjectsFromMultipleFolders;[AssetSelector(Filter = "name t:type l:label")]public UnityEngine.Object AssetDatabaseSearchFilters;[Title("Other Minor Features")][AssetSelector(DisableListAddButtonBehaviour = true)]public List<GameObject> DisableListAddButtonBehaviour;[AssetSelector(DrawDropdownForListElements = false)]public List<GameObject> DisableListElementBehaviour;[AssetSelector(ExcludeExistingValuesInList = false)]public List<GameObject> ExcludeExistingValuesInList;[AssetSelector(IsUniqueList = false)]public List<GameObject> DisableUniqueListBehaviour;[AssetSelector(ExpandAllMenuItems = true)]public List<GameObject> ExpandAllMenuItems;[AssetSelector(DropdownTitle = "Custom Dropdown Title")]public List<GameObject> CustomDropdownTitle;
}

2.3 ChildGameObjectsOnly

可用于 Components 和 GameObject,并在对象旁添加小按钮,点击按钮将显示其子物体中所有满足条件的对象。

  • IncludeSelf = true

    是否包含自身。

  • bool IncludeInactive

    是否包含未激活的子物体。

image-20240718021903335
// ChildGameObjectsOnlyAttributeExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class ChildGameObjectsOnlyAttributeExamplesComponent : MonoBehaviour
{[ChildGameObjectsOnly]public Transform ChildOrSelfTransform;[ChildGameObjectsOnly]public GameObject ChildGameObject;[ChildGameObjectsOnly(IncludeSelf = false)]public Light[] Lights;
}

2.4 ColorPalette

用于任何 Color,允许从一组预定义的颜色选项中进行选择。

  • string paletteName

    调色板名称。

  • bool ShowAlpha = true

    是否显示透明度。

image-20240718022418293
// ColorPaletteExamplesComponent.csusing Sirenix.OdinInspector;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;public class ColorPaletteExamplesComponent : MonoBehaviour
{[ColorPalette]public Color ColorOptions;[ColorPalette("Underwater")]public Color UnderwaterColor;[ColorPalette("My Palette")]public Color MyColor;public string DynamicPaletteName = "Clovers";// The ColorPalette attribute supports both // member references and attribute expressions.[ColorPalette("$DynamicPaletteName")]public Color DynamicPaletteColor;[ColorPalette("Fall"), HideLabel]public Color WideColorPalette;[ColorPalette("Clovers")]public Color[] ColorArray;// ------------------------------------// Color palettes can be accessed and modified from code.// Note that the color palettes will NOT automatically be included in your builds.// But you can easily fetch all color palettes via the ColorPaletteManager // and include them in your game like so:// ------------------------------------[FoldoutGroup("Color Palettes", expanded: false)][ListDrawerSettings(IsReadOnly = true)][PropertyOrder(9)]public List<ColorPalette> ColorPalettes;[Serializable]public class ColorPalette{[HideInInspector]public string Name;[LabelText("$Name")][ListDrawerSettings(IsReadOnly = true, ShowFoldout = false)]public Color[] Colors;}#if UNITY_EDITOR[FoldoutGroup("Color Palettes"), Button(ButtonSizes.Large), GUIColor(0, 1, 0), PropertyOrder(8)]private void FetchColorPalettes() {this.ColorPalettes = Sirenix.OdinInspector.Editor.ColorPaletteManager.Instance.ColorPalettes.Select(x => new ColorPalette() {Name   = x.Name,Colors = x.Colors.ToArray()}).ToList();}
#endif
}

2.5 DisplayAsString

用于任何对象,在 Inpector 窗口中将对象显示为字符串文本。想在 Inpector 窗口中显示字符串,但不允许进行任何编辑时,请使用此选项。

  • bool overflow

    true:字符串将溢出绘制的空间,并在没有足够的空间容纳文本时被剪切。

    false:如果绘制时没有足够的空间,字符串将扩展为多行。

  • int fontSize

    字体大小。

  • TextAlignment alignment

    对齐方式。

  • bool enableRichText

    是否开启富文本。

  • string Format

    用于格式化值的字符串。类型必须实现 IFormattable 接口。

image-20240718022535984
// DisplayAsStringExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class DisplayAsStringExamplesComponent : MonoBehaviour
{[InfoBox("Instead of disabling values in the inspector in order to show some information or debug a value. " +"You can use DisplayAsString to show the value as text, instead of showing it in a disabled drawer")][DisplayAsString]public Color SomeColor;[BoxGroup("SomeBox")][HideLabel][DisplayAsString]public string SomeText = "Lorem Ipsum";[InfoBox("The DisplayAsString attribute can also be configured to enable or disable overflowing to multiple lines.")][HideLabel][DisplayAsString]public string Overflow = "A very very very very very very very very very long string that has been configured to overflow.";[HideLabel][DisplayAsString(false)]public string DisplayAllOfIt = "A very very very very very very very very long string that has been configured to not overflow.";[InfoBox("Additionally, you can also configure the string's alignment, font size, and whether it should support rich text or not.")][DisplayAsString(false, 20, TextAlignment.Center, true)]public string CustomFontSizeAlignmentAndRichText = "This string is <b><color=#FF5555><i>super</i> <size=24>big</size></color></b> and centered.";
}

2.6 EnumPaging

为枚举添加“下一步”和“上一步”按钮选择器,循环查看枚举属性的可用值。

image-20240715003928053
// EnumPagingExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class EnumPagingExamplesComponent : MonoBehaviour
{[EnumPaging]public SomeEnum SomeEnumField;public enum SomeEnum{A, B, C}#if UNITY_EDITOR // UnityEditor.Tool is an editor-only type, so this example will not work in a build[EnumPaging, OnValueChanged("SetCurrentTool")][InfoBox("Changing this property will change the current selected tool in the Unity editor.")]public UnityEditor.Tool sceneTool;private void SetCurrentTool() {UnityEditor.Tools.current = this.sceneTool;}
#endif
}

2.7 EnumToggleButtons

在水平按钮组中绘制枚举,而不是下拉列表。

image-20240715004031983
// EnumToggleButtonsExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class EnumToggleButtonsExamplesComponent : MonoBehaviour
{[Title("Default")]public SomeBitmaskEnum DefaultEnumBitmask;[Title("Standard Enum")][EnumToggleButtons]public SomeEnum SomeEnumField; // 单选枚举[EnumToggleButtons, HideLabel]public SomeEnum WideEnumField; // 单选枚举[Title("Bitmask Enum")][EnumToggleButtons]public SomeBitmaskEnum BitmaskEnumField; // 多选枚举[EnumToggleButtons, HideLabel]public SomeBitmaskEnum EnumFieldWide; // 多选枚举[Title("Icon Enum")][EnumToggleButtons, HideLabel]public SomeEnumWithIcons EnumWithIcons;[EnumToggleButtons, HideLabel]public SomeEnumWithIconsAndNames EnumWithIconsAndNames;public enum SomeEnum{First, Second, Third, Fourth, AndSoOn}public enum SomeEnumWithIcons{[LabelText(SdfIconType.TextLeft)]   TextLeft,[LabelText(SdfIconType.TextCenter)] TextCenter,[LabelText(SdfIconType.TextRight)]  TextRight,}public enum SomeEnumWithIconsAndNames{[LabelText("Align Left", SdfIconType.TextLeft)]TextLeft,[LabelText("Align Center", SdfIconType.TextCenter)]TextCenter,[LabelText("Align Right", SdfIconType.TextRight)]TextRight,}[System.Flags]public enum SomeBitmaskEnum{A   = 1 << 1,B   = 1 << 2,C   = 1 << 3,All = A | B | C}
}

2.8 FilePath

用于字符串,为文件路径提供接口。支持下拉选择文件路径和拖拽文件路径。

  • string ParentFolder

    父路径。可以相对于 Unity 项目,也可以是绝对路径。

  • string Extensions

    文件扩展名列表(以逗号分隔)。扩展名中的 “.” 可不写。

  • bool AbsolutePath

    是否为绝对路径。

  • bool RequireExistingPath

    true:若路径不存在,则显示警告提示。

  • bool UseBackslashes

    是否使用反斜杠(默认使用斜杠)。

image-20240718024034855
// FilePathExamplesComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;public class FilePathExamplesComponent : MonoBehaviour
{// By default, FolderPath provides a path relative to the Unity project.[FilePath]public string UnityProjectPath;// It is possible to provide custom parent path. Parent paths can be relative to the Unity project, or absolute.[FilePath(ParentFolder = "Assets/Plugins/Sirenix")]public string RelativeToParentPath;// Using parent path, FilePath can also provide a path relative to a resources folder.[FilePath(ParentFolder = "Assets/Resources")]public string ResourcePath;// Provide a comma seperated list of allowed extensions. Dots are optional.[FilePath(Extensions = "cs")][BoxGroup("Conditions")]public string ScriptFiles;// By setting AbsolutePath to true, the FilePath will provide an absolute path instead.[FilePath(AbsolutePath = true)][BoxGroup("Conditions")]public string AbsolutePath;// FilePath can also be configured to show an error, if the provided path is invalid.[FilePath(RequireExistingPath = true)][BoxGroup("Conditions")]public string ExistingPath;// By default, FilePath will enforce the use of forward slashes. It can also be configured to use backslashes instead.[FilePath(UseBackslashes = true)][BoxGroup("Conditions")]public string Backslashes;// 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/Plugins/Sirenix";[BoxGroup("Member referencing")]public string DynamicExtensions = "cs, unity, jpg";// FilePath also supports lists and arrays.[FilePath(ParentFolder = "Assets/Plugins/Sirenix/Demos/Odin Inspector")][BoxGroup("Lists")]public string[] ListOfFiles;
}

2.9 FolderPath

用于字符串,为目录路径提供接口。支持下拉选择文件夹目录和拖拽文件夹目录。

  • string ParentFolder

    父路径。可以相对于 Unity 项目,也可以是绝对路径。

  • bool AbsolutePath

    是否为绝对路径。

  • bool RequireExistingPath

    true:若路径不存在,则显示警告提示。

  • bool UseBackslashes

    是否使用反斜杠(默认使用斜杠)。

image-20240718024439650
// FolderPathExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class FolderPathExamplesComponent : MonoBehaviour
{// By default, FolderPath provides a path relative to the Unity project.[FolderPath]public string UnityProjectPath;// It is possible to provide custom parent path. Parent paths can be relative to the Unity project, or absolute.[FolderPath(ParentFolder = "Assets/Plugins/Sirenix")]public string RelativeToParentPath;// Using parent path, FolderPath can also provide a path relative to a resources folder.[FolderPath(ParentFolder = "Assets/Resources")]public string ResourcePath;// By setting AbsolutePath to true, the FolderPath will provide an absolute path instead.[FolderPath(AbsolutePath = true)][BoxGroup("Conditions")]public string AbsolutePath;// FolderPath can also be configured to show an error, if the provided path is invalid.[FolderPath(RequireExistingPath = true)][BoxGroup("Conditions")]public string ExistingPath;// By default, FolderPath will enforce the use of forward slashes. It can also be configured to use backslashes instead.[FolderPath(UseBackslashes = true)][BoxGroup("Conditions")]public string Backslashes;// FolderPath also supports member references and attribute expressions with the $ symbol.[FolderPath(ParentFolder = "$DynamicParent")][BoxGroup("Member referencing")]public string DynamicFolderPath;[BoxGroup("Member referencing")]public string DynamicParent = "Assets/Plugins/Sirenix";// FolderPath also supports lists and arrays.[FolderPath(ParentFolder = "Assets/Plugins/Sirenix")][BoxGroup("Lists")]public string[] ListOfFolders;
}

2.10 HideInInlineEditors

如果对象被 InlineEditor 特性绘制,则该对象在 Inspector 窗口中隐藏。

补充 InlineEditor 特性:将继承 UnityEngine.Object 的类(如 ScriptableObject)的详细信息显示在 Inspector 窗口。

image-20240718025035866

​ 数据结构类:

using UnityEngine;#nullable disable
namespace Sirenix.OdinInspector.Editor.Examples
{public class MyInlineScriptableObject : ScriptableObject{[ShowInInlineEditors]public string ShownInInlineEditor;[HideInInlineEditors]public string HiddenInInlineEditor;}
}

​ 挂载的脚本:

// ShowAndHideInInlineEditorExampleComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.OdinInspector.Editor.Examples;
#endifpublic class ShowAndHideInInlineEditorExampleComponent : MonoBehaviour
{
#if UNITY_EDITOR // MyInlineScriptableObject is an example type and only exists in the editor[InfoBox("Click the pen icon to open a new inspector window for the InlineObject too see the differences these attributes make.")][InlineEditor(Expanded = true)]public MyInlineScriptableObject InlineObject;
#endif#if UNITY_EDITOR // Editor-related code must be excluded from builds[OnInspectorInit]private void CreateData(){InlineObject = ExampleHelper.GetScriptableObject<MyInlineScriptableObject>("Inline Object");}[OnInspectorDispose]private void CleanupData(){if (InlineObject != null) Object.DestroyImmediate(InlineObject);}
#endif
}

2.11 HideInTables

用于防止对象在使用 TableListAttribute 绘制的表中显示为列。

image-20240718025150278
// HideInTablesExampleComponent.csusing Sirenix.OdinInspector;
using System;
using System.Collections.Generic;
using UnityEngine;public class HideInTablesExampleComponent : MonoBehaviour
{public MyItem Item = new MyItem();[TableList]public List<MyItem> Table = new List<MyItem>() {new MyItem(),new MyItem(),new MyItem(),};[Serializable]public class MyItem{public string A;public int B;[HideInTables]public int Hidden;}
}

2.12 HideMonoScript

阻止某个类型的所有对象在 Inspector窗口中显示其成员。

image-20240718030213540

​ 数据结构类:

using UnityEngine;#nullable disable
namespace Sirenix.OdinInspector.Editor.Examples
{public class ShowMonoScriptScriptableObject : ScriptableObject{public string Value;}[HideMonoScript]public class HideMonoScriptScriptableObject : ScriptableObject{public string Value;}
}

​ 挂载的脚本:

// HideMonoScriptExampleComponent.csusing Sirenix.OdinInspector;
using UnityEngine;#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.OdinInspector.Editor.Examples;
#endifpublic class HideMonoScriptExampleComponent : MonoBehaviour
{
#if UNITY_EDITOR // HideMonoScriptScriptableObject and ShowMonoScriptScriptableObject are example types and only exist in the editor[InfoBox("Click the pencil icon to open new inspector for these fields.")]public HideMonoScriptScriptableObject Hidden;// The script will also be hidden for the ShowMonoScript object if MonoScripts are hidden globally.public ShowMonoScriptScriptableObject Shown;
#endif#if UNITY_EDITOR // Editor-related code must be excluded from builds[OnInspectorInit]private void CreateData() {Hidden = ExampleHelper.GetScriptableObject<HideMonoScriptScriptableObject>("Hidden");Shown  = ExampleHelper.GetScriptableObject<ShowMonoScriptScriptableObject>("Shown");}[OnInspectorDispose]private void CleanupData() {if (Hidden != null) Object.DestroyImmediate(Hidden);if (Shown != null) Object.DestroyImmediate(Shown);}
#endif
}

2.13 HideReferenceObjectPicker

将多态对象选择器隐藏在非 Unity 序列化引用类型的属性中。
当对象选择器隐藏时,可以右键单击并将实例设置为 null,以设置新值。

也可以使用 DisableContextMenu 特性来确保无法更改该值。

image-20240718030548801
// HideReferenceObjectPickerExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class HideReferenceObjectPickerExamplesComponent : SerializedMonoBehaviour
{[Title("Hidden Object Pickers")][HideReferenceObjectPicker]public MyCustomReferenceType OdinSerializedProperty1 = new MyCustomReferenceType();[HideReferenceObjectPicker]public MyCustomReferenceType OdinSerializedProperty2 = new MyCustomReferenceType();[Title("Shown Object Pickers")]public MyCustomReferenceType OdinSerializedProperty3 = new MyCustomReferenceType();public MyCustomReferenceType OdinSerializedProperty4 = new MyCustomReferenceType();// Protip: You can also put the HideInInspector attribute on the class definition itself to hide it globally for all members.// [HideReferenceObjectPicker]public class MyCustomReferenceType{public int A;public int B;public int C;}
}

2.14 InlineEditor

将继承 UnityEngine.Object 的类(如 ScriptableObject)的详细信息显示在 Inspector 窗口。

  • InlineEditorModes inlineEditorMode = InlineEditorModes.GUIOnly

    绘制模式。

  • InlineEditorObjectFieldModes objectFieldMode = InlineEditorObjectFieldModes.Boxed

    绘制方式。

image-20240718031212511
// InlineEditorExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.OdinInspector.Editor.Examples;
#endifpublic class InlineEditorExamplesComponent : MonoBehaviour
{
#if UNITY_EDITOR // ExampleTransform is an example type and only exists in the editor[InlineEditor]public ExampleTransform InlineComponent;
#endif[InlineEditor(InlineEditorModes.FullEditor)]public Material FullInlineEditor;[InlineEditor(InlineEditorModes.GUIAndHeader)]public Material InlineMaterial;[InlineEditor(InlineEditorModes.SmallPreview)]public Material[] InlineMaterialList;[InlineEditor(InlineEditorModes.LargePreview)]public Mesh InlineMeshPreview;// You can also use the InlineEditor attribute directly on a class definition itself!//[InlineEditor]//public class ExampleTransform : ScriptableObject//{//    public Vector3 Position;//    public Quaternion Rotation;//    public Vector3 Scale = Vector3.one;//}#if UNITY_EDITOR // Editor-related code must be excluded from builds[OnInspectorInit]private void CreateData() {InlineComponent  = ExampleHelper.GetScriptableObject<ExampleTransform>("Inline Component");FullInlineEditor = ExampleHelper.GetMaterial();InlineMaterial   = ExampleHelper.GetMaterial();InlineMaterialList = new Material[] {ExampleHelper.GetMaterial(),ExampleHelper.GetMaterial(),ExampleHelper.GetMaterial(),};InlineMeshPreview = ExampleHelper.GetMesh();}[OnInspectorDispose]private void CleanupData() {if (InlineComponent != null) Object.DestroyImmediate(InlineComponent);}
#endif
}

2.15 Multiline

使用多行文本字段编辑字符串。

  • int lines = 3

    行数。

image-20240718031531320
// MultiLinePropertyExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class MultiLinePropertyExamplesComponent : MonoBehaviour
{// Unity's TextArea and Multiline attributes and Odin's MultiLineProperty attribute// are all very similar.// // TextArea specifies a minimum and maximum number of lines. It will display at least// the minimum number of lines, but will expand with its content up to the maximum// number of lines, and display a scrollbar past that.// // Multiline and MultiLineProperty are given a precise number of lines to occupy and// will never contract or expand based on contents; instead they display a scrollbar// if the content does not fit into the given number of lines.// // Finally, unlike Multiline, Odin's MultiLineProperty can be applied to any member// type including fields, properties, method arguments, types, and so on.[TextArea(4, 10)]public string UnityTextAreaField = "";[Multiline(10)]public string UnityMultilineField = "";[Title("Wide Multiline Text Field", bold: false)][HideLabel][MultiLineProperty(10)]public string WideMultilineTextField = "";[InfoBox("Odin supports properties, but Unity's own Multiline attribute only works on fields.")][ShowInInspector][MultiLineProperty(10)]public string OdinMultilineProperty { get; set; }
}

2.16 PreviewField

绘制方形 ObjectField,预览对象类型。

  1. 拖拽对象到另一个对象,将交换值。
  2. 按住 ctrl 同时松开,将替换值。
  3. 按住 ctrl 并单击对象,将快速删除值。

可以从 Odin 首选项窗口选择性启用和全局自定义操作。

  • string previewGetter

    预览纹理的解析值。

  • float height

    预览窗口高度。

  • ObjectFieldAlignment alignment

    预览窗口对齐方式。

  • FilterMode filterMode = FilterMode.Bilinear

    预览纹理的过滤模式。

image-20240718032140205
// PreviewFieldExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.OdinInspector.Editor.Examples;
#endifpublic class PreviewFieldExamplesComponent : MonoBehaviour
{[PreviewField]public Object RegularPreviewField;[VerticalGroup("row1/left")]public string A, B, C;[HideLabel][PreviewField(50, ObjectFieldAlignment.Right)][HorizontalGroup("row1", 50), VerticalGroup("row1/right")]public Object D;[HideLabel][PreviewField(50, ObjectFieldAlignment.Left)][HorizontalGroup("row2", 50), VerticalGroup("row2/left")]public Object E;[VerticalGroup("row2/right"), LabelWidth(-54)]public string F, G, H;[PreviewField("preview", FilterMode.Bilinear)]public Object I;private Texture preview;#if UNITY_EDITOR // Editor-related code must be excluded from builds[OnInspectorInit]private void CreateData() {RegularPreviewField = ExampleHelper.GetTexture();D                   = ExampleHelper.GetTexture();E                   = ExampleHelper.GetTexture();I                   = ExampleHelper.GetMesh();preview             = ExampleHelper.GetTexture();}[InfoBox("These object fields can also be selectively enabled and customized globally " +"from the Odin preferences window.\n\n" +" - Hold Ctrl + Click = Delete Instance\n" +" - Drag and drop = Move / Swap.\n" +" - Ctrl + Drag = Replace.\n" +" - Ctrl + drag and drop = Move and override.")][PropertyOrder(-1)][Button(ButtonSizes.Large)]private void ConfigureGlobalPreviewFieldSettings() {Sirenix.OdinInspector.Editor.GeneralDrawerConfig.Instance.OpenInEditor();}
#endif
}

2.17 PolymorphicDrawerSettings

提供“多态类型”的绘制选项。

  • bool ShowBaseType

    是否显示基类。

  • bool ReadOnlyIfNotNullReference

    对象一旦被赋值,是否还可以改变。

  • NonDefaultConstructorPreference NonDefaultConstructorPreference

    指定如何处理非默认构造函数。

  • string CreateInstanceFunction

    指定自定义函数,用于创建所选对象的实例。

image-20240718033449480
// PolymorphicDrawerSettingsExampleComponent.csusing System;
using Sirenix.OdinInspector;
using Sirenix.Serialization;
using Sirenix.Utilities;
using UnityEngine;public class PolymorphicDrawerSettingsExampleComponent : MonoBehaviour
{[ShowInInspector]public IDemo<int> Default;[Title("Show Base Type"), ShowInInspector, LabelText("On")][PolymorphicDrawerSettings(ShowBaseType = true)]public IDemo<int> ShowBaseType_On;[ShowInInspector, LabelText("Off")][PolymorphicDrawerSettings(ShowBaseType = false)]public IDemo<int> ShowBaseType_Off;[Title("Read Only If Not Null Reference"), ShowInInspector, LabelText("On")][PolymorphicDrawerSettings(ReadOnlyIfNotNullReference = true)]public IDemo<int> ReadOnlyIfNotNullReference_On;[ShowInInspector, LabelText("Off")][PolymorphicDrawerSettings(ReadOnlyIfNotNullReference = false)]public IDemo<int> ReadOnlyIfNotNullReference_Off;[Title("Non Default Constructor Preference"), ShowInInspector, LabelText("Exclude")][PolymorphicDrawerSettings(NonDefaultConstructorPreference = NonDefaultConstructorPreference.Exclude)]public IVector2<int> NonDefaultConstructorPreference_Ignore;[ShowInInspector, LabelText("Construct Ideal")][PolymorphicDrawerSettings(NonDefaultConstructorPreference = NonDefaultConstructorPreference.ConstructIdeal)]public IVector2<int> NonDefaultConstructorPreference_ConstructIdeal;[ShowInInspector, LabelText("Prefer Uninitialized")][PolymorphicDrawerSettings(NonDefaultConstructorPreference = NonDefaultConstructorPreference.PreferUninitialized)]public IVector2<int> NonDefaultConstructorPreference_PreferUninit;[ShowInInspector, LabelText("Log Warning")][PolymorphicDrawerSettings(NonDefaultConstructorPreference = NonDefaultConstructorPreference.LogWarning)]public IVector2<int> NonDefaultConstructorPreference_LogWarning;[Title("Create Custom Instance"), ShowInInspector][PolymorphicDrawerSettings(CreateInstanceFunction = nameof(CreateInstance))]public IVector2<int> CreateCustomInstance;private IVector2<int> CreateInstance(Type type){Debug.Log("Constructor called for " + type + '.');if (typeof(SomeNonDefaultCtorClass) == type){return new SomeNonDefaultCtorClass(485);}return type.InstantiateDefault(false) as IVector2<int>;}public interface IVector2<T>{T X { get; set; }T Y { get; set; }}[Serializable]public class SomeNonDefaultCtorClass : IVector2<int>{[OdinSerialize]public int X { get; set; }[OdinSerialize]public int Y { get; set; }public SomeNonDefaultCtorClass(int x){this.X = x;this.Y = (x + 1) * 4;}}public interface IDemo<T>{T Value { get; set; }}[Serializable]public class DemoSOInt32 : SerializedScriptableObject, IDemo<int>{[OdinSerialize]public int Value { get; set; }}[Serializable]public class DemoSOInt32Target : SerializedScriptableObject, IDemo<int>{[OdinSerialize]public int Value { get; set; }public int target;}[Serializable]public class DemoSOFloat32 : SerializedScriptableObject, IDemo<float>{[OdinSerialize]public float Value { get; set; }}[Serializable]public class Demo<T> : IDemo<T>{[OdinSerialize]public T Value { get; set; }}[Serializable]public class DemoInt32Interface : IDemo<int>{[OdinSerialize]public int Value { get; set; }}public class DemoInt32 : Demo<int> { }public struct DemoStructInt32 : IDemo<int>{[OdinSerialize]public int Value { get; set; }}
}

2.18 TypeDrawerSettings

提供“类型”的绘制选项。

  • Type BaseType

    指定是否应使用基类型而不是所有类型。

  • TypeInclusionFilter Filter = TypeInclusionFilter.IncludeAll;

    过滤类型的方法。

image-20240718034227737
// TypeDrawerSettingsAttributeExampleComponent.csusing System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Sirenix.OdinInspector;
using UnityEngine;public class TypeDrawerSettingsAttributeExampleComponent : MonoBehaviour
{[ShowInInspector]public Type Default;[Title("Base Type"), ShowInInspector, LabelText("Set")][TypeDrawerSettings(BaseType = typeof(IEnumerable<>))]public Type BaseType_Set;[ShowInInspector, LabelText("Not Set")][TypeDrawerSettings(BaseType = null)]public Type BaseType_NotSet;[Title(nameof(TypeDrawerSettingsAttribute.Filter)), ShowInInspector, LabelText("Concrete Types")][TypeDrawerSettings(BaseType = typeof(IBaseGeneric<>), Filter = TypeInclusionFilter.IncludeConcreteTypes)]public Type Filter_Default;[ShowInInspector, LabelText("Concrete- && Generic Types")][TypeDrawerSettings(BaseType = typeof(IBaseGeneric<>), Filter = TypeInclusionFilter.IncludeConcreteTypes | TypeInclusionFilter.IncludeGenerics)]public Type Filter_Generics;[ShowInInspector, LabelText("Concrete- && Interface Types")][TypeDrawerSettings(BaseType = typeof(IBaseGeneric<>), Filter = TypeInclusionFilter.IncludeConcreteTypes | TypeInclusionFilter.IncludeInterfaces)]public Type Filter_Interfaces;[ShowInInspector, LabelText("Concrete- && Abstract Types")][TypeDrawerSettings(BaseType = typeof(IBaseGeneric<>), Filter = TypeInclusionFilter.IncludeConcreteTypes | TypeInclusionFilter.IncludeAbstracts)]public Type Filter_Abstracts;[ShowInInspector, LabelText("Concrete-, Abstract- && Generic Types")][TypeDrawerSettings(BaseType = typeof(IBaseGeneric<>), Filter = TypeInclusionFilter.IncludeConcreteTypes |TypeInclusionFilter.IncludeAbstracts |TypeInclusionFilter.IncludeGenerics)]public Type Filter_Abstracts_Generics;[ShowInInspector, LabelText("Concrete-, Interface- && Generic Types")][TypeDrawerSettings(BaseType = typeof(IBaseGeneric<>), Filter = TypeInclusionFilter.IncludeConcreteTypes |TypeInclusionFilter.IncludeInterfaces |TypeInclusionFilter.IncludeGenerics)]public Type Filter_Interfaces_Generics;[ShowInInspector, LabelText("Concrete-, Interface- && Abstract Types")][TypeDrawerSettings(BaseType = typeof(IBaseGeneric<>), Filter = TypeInclusionFilter.IncludeConcreteTypes |TypeInclusionFilter.IncludeInterfaces |TypeInclusionFilter.IncludeAbstracts)]public Type Filter_Interfaces_Abstracts;[ShowInInspector, LabelText("All")][TypeDrawerSettings(BaseType = typeof(IBaseGeneric<>), Filter = TypeInclusionFilter.IncludeAll)]public Type Filter_All;public interface IBaseGeneric<T>{ }public interface IBase : IBaseGeneric<int>{ }public abstract class Base : IBase{ }public class Concrete : Base{ }public class ConcreteGeneric<T> : Base{ }public abstract class BaseGeneric<T> : IBase{ }[CompilerGenerated]public class ConcreteGenerated : Base{ }
}

2.19 SceneObjectsOnly

使目标对象在 Inspector 窗口中只能场景对象,限制拖拽的资源类型。

image-20240715004717713
// SceneAndAssetsOnlyExamplesComponent.csusing Sirenix.OdinInspector;
using System.Collections.Generic;
using UnityEngine;public class SceneAndAssetsOnlyExamplesComponent : MonoBehaviour
{[Title("Assets only")][AssetsOnly]public List<GameObject> OnlyPrefabs;[AssetsOnly]public GameObject SomePrefab;[AssetsOnly]public Material MaterialAsset;[AssetsOnly]public MeshRenderer SomeMeshRendererOnPrefab;[Title("Scene Objects only")][SceneObjectsOnly]public List<GameObject> OnlySceneObjects;[SceneObjectsOnly]public GameObject SomeSceneObject;[SceneObjectsOnly]public MeshRenderer SomeMeshRenderer;
}

2.20 TableList

将 List 绘制成表格形状。

  • bool IsReadOnly = true

    是否在 Inspector 窗口中只读。

  • int NumberOfItemsPerPage

    列表每页的成员个数,超过该个数则会翻页。

  • bool ShowIndexLabels

    是否显示列表每个 item 的下标。

  • bool ShowPaging = true

    是否启用分页显示。

  • bool ShowItemCount = true

    是否显示成员个数。

  • bool HideToolbar = false

    是否隐藏标题栏。

  • bool DrawScrollView = true

    是否绘制滚动条。

  • int MaxScrollViewHeight/MinScrollViewHeight

    滚动条绘制的范围(最大高度/最小高度),单位:像素。

  • bool AlwaysExpanded

    List 是否可折叠。

image-20240715021626235
// TableListExamplesComponent.csusing Sirenix.OdinInspector;
using System;
using System.Collections.Generic;
using UnityEngine;#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.OdinInspector.Editor.Examples;
#endifpublic class TableListExamplesComponent : MonoBehaviour
{[TableList(ShowIndexLabels = true)]public List<SomeCustomClass> TableListWithIndexLabels = new List<SomeCustomClass>() {new SomeCustomClass(),new SomeCustomClass(),};[TableList(DrawScrollView = true, MaxScrollViewHeight = 200, MinScrollViewHeight = 100)]public List<SomeCustomClass> MinMaxScrollViewTable = new List<SomeCustomClass>() {new SomeCustomClass(),new SomeCustomClass(),};[TableList(AlwaysExpanded = true, DrawScrollView = false)]public List<SomeCustomClass> AlwaysExpandedTable = new List<SomeCustomClass>() {new SomeCustomClass(),new SomeCustomClass(),};[TableList(ShowPaging = true, NumberOfItemsPerPage = 3)]public List<SomeCustomClass> TableWithPaging = new List<SomeCustomClass>() {new SomeCustomClass(),new SomeCustomClass(),};[Serializable]public class SomeCustomClass{[TableColumnWidth(57, Resizable = false)][PreviewField(Alignment = ObjectFieldAlignment.Center)]public Texture Icon;[TextArea]public string Description;[VerticalGroup("Combined Column"), LabelWidth(22)]public string A, B, C;[TableColumnWidth(60)][Button, VerticalGroup("Actions")]public void Test1() { }[TableColumnWidth(60)][Button, VerticalGroup("Actions")]public void Test2() { }#if UNITY_EDITOR // Editor-related code must be excluded from builds[OnInspectorInit]private void CreateData() {Description = ExampleHelper.GetString();Icon        = ExampleHelper.GetTexture();}
#endif}
}

2.21 TableMatrix

绘制二维数组。

  1. 单元格绘制。

    • string HorizontalTitle

      水平标题。

    • bool SquareCells

      如果为 true,则每行的高度将与第一个单元格的宽度相同。

image-20240715022259336
// TableMatrixExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.OdinInspector.Editor.Examples;
#endifpublic class TableMatrixExamplesComponent : SerializedMonoBehaviour
{[TableMatrix(HorizontalTitle = "Square Celled Matrix", SquareCells = true)]public Texture2D[,] SquareCelledMatrix;[TableMatrix(SquareCells = true)]public Mesh[,] PrefabMatrix;#if UNITY_EDITOR // Editor-related code must be excluded from builds[OnInspectorInit]private void CreateData() {SquareCelledMatrix = new Texture2D[8, 4] {{ ExampleHelper.GetTexture(), null, null, null },{ null, ExampleHelper.GetTexture(), null, null },{ null, null, ExampleHelper.GetTexture(), null },{ null, null, null, ExampleHelper.GetTexture() },{ ExampleHelper.GetTexture(), null, null, null },{ null, ExampleHelper.GetTexture(), null, null },{ null, null, ExampleHelper.GetTexture(), null },{ null, null, null, ExampleHelper.GetTexture() },};PrefabMatrix = new Mesh[8, 4] {{ ExampleHelper.GetMesh(), null, null, null },{ null, ExampleHelper.GetMesh(), null, null },{ null, null, ExampleHelper.GetMesh(), null },{ null, null, null, ExampleHelper.GetMesh() },{ null, null, null, ExampleHelper.GetMesh() },{ null, null, ExampleHelper.GetMesh(), null },{ null, ExampleHelper.GetMesh(), null, null },{ ExampleHelper.GetMesh(), null, null, null },};}
#endif
}
  1. 表格绘制

    • bool IsReadOnly

      如果为 true,则插入、删除和拖动列和行将不可用。但单元格本身仍将是可修改的。

      如果要禁用所有内容,可以使用 ReadOnly 属性。

    • string VerticalTitle

      垂直标题。

image-20240715022550956
// TableMatrixTitleExampleComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class TableMatrixTitleExampleComponent : SerializedMonoBehaviour
{[TableMatrix(HorizontalTitle = "Read Only Matrix", IsReadOnly = true)]public int[,] ReadOnlyMatrix = new int[5, 5];[TableMatrix(HorizontalTitle = "X axis", VerticalTitle = "Y axis")]public InfoMessageType[,] LabledMatrix = new InfoMessageType[6, 6];
}
  1. 图形绘制

    • string DrawElementMethod

      覆盖绘制每个单元格的方式。

      输入参数:Rect rect, T value

      输出:T

    • bool ResizableColumns = true

      列是否可调整大小。

    • RowHeight

      行高,0 表示默认高度。

    • bool Transpose

      如果为 true,则表的行/列颠倒绘制(C# 初始化顺序)。

image-20240715023026208
// TransposeTableMatrixExampleComponent.csusing Sirenix.OdinInspector;
using Sirenix.Utilities;
using UnityEngine;public class TransposeTableMatrixExampleComponent : SerializedMonoBehaviour
{[TableMatrix(HorizontalTitle = "Custom Cell Drawing", DrawElementMethod = nameof(DrawColoredEnumElement), ResizableColumns = false, RowHeight = 16)]public bool[,] CustomCellDrawing;[ShowInInspector, DoNotDrawAsReference][TableMatrix(HorizontalTitle = "Transposed Custom Cell Drawing", DrawElementMethod = "DrawColoredEnumElement", ResizableColumns = false, RowHeight = 16, Transpose = true)]public bool[,] Transposed { get { return CustomCellDrawing; } set { CustomCellDrawing = value; } }#if UNITY_EDITOR // Editor-related code must be excluded from buildsprivate static bool DrawColoredEnumElement(Rect rect, bool value) {if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) {value       = !value;GUI.changed = true;Event.current.Use();}UnityEditor.EditorGUI.DrawRect(rect.Padding(1), value ? new Color(0.1f, 0.8f, 0.2f) : new Color(0, 0, 0, 0.5f));return value;}[OnInspectorInit]private void CreateData() {// =)this.CustomCellDrawing        = new bool[15, 15];this.CustomCellDrawing[6, 5]  = true;this.CustomCellDrawing[6, 6]  = true;this.CustomCellDrawing[6, 7]  = true;this.CustomCellDrawing[8, 5]  = true;this.CustomCellDrawing[8, 6]  = true;this.CustomCellDrawing[8, 7]  = true;this.CustomCellDrawing[5, 9]  = true;this.CustomCellDrawing[5, 10] = true;this.CustomCellDrawing[9, 9]  = true;this.CustomCellDrawing[9, 10] = true;this.CustomCellDrawing[6, 11] = true;this.CustomCellDrawing[7, 11] = true;this.CustomCellDrawing[8, 11] = true;}
#endif
}

2.22 Toggle

将对象放在开关组中绘制。

  • string toggleMemberName

    用于启用或禁用对象的任何 bool 字段或属性的名称。

  • bool CollapseOthersOnExpand = true

    如果为 true,其中一个打开,其他的开关组都将折叠显示。

image-20240718034704631
// ToggleExampleComponent.csusing Sirenix.OdinInspector;
using System;
using UnityEngine;public class ToggleExampleComponent : MonoBehaviour
{[Toggle("Enabled")]public MyToggleable Toggler = new MyToggleable();public ToggleableClass Toggleable = new ToggleableClass();[Serializable]public class MyToggleable{public bool Enabled;public int  MyValue;}// You can also use the Toggle attribute directly on a class definition.[Serializable, Toggle("Enabled")]public class ToggleableClass{public bool   Enabled;public string Text;}
}

2.23 ToggleGroup

将对象添加进单选框组。

  • string toggleMemberName

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

  • float order = 0.0f

    单选框组的排序。

  • string groupTitle = null

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

image-20240716043131827
// ToggleGroupExamplesComponent.csusing 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;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com