文章目录
- 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。
// 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
自定义下拉列表标题。
// 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
是否包含未激活的子物体。
// 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
是否显示透明度。
// 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 接口。
// 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
为枚举添加“下一步”和“上一步”按钮选择器,循环查看枚举属性的可用值。
// 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
在水平按钮组中绘制枚举,而不是下拉列表。
// 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
是否使用反斜杠(默认使用斜杠)。
// 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
是否使用反斜杠(默认使用斜杠)。
// 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 窗口。
数据结构类:
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 绘制的表中显示为列。
// 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窗口中显示其成员。
数据结构类:
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 特性来确保无法更改该值。
// 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
绘制方式。
2.15 Multiline
使用多行文本字段编辑字符串。
int lines = 3
行数。
// 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,预览对象类型。
- 拖拽对象到另一个对象,将交换值。
- 按住 ctrl 同时松开,将替换值。
- 按住 ctrl 并单击对象,将快速删除值。
可以从 Odin 首选项窗口选择性启用和全局自定义操作。
string previewGetter
预览纹理的解析值。
float height
预览窗口高度。
ObjectFieldAlignment alignment
预览窗口对齐方式。
FilterMode filterMode = FilterMode.Bilinear
预览纹理的过滤模式。
// 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
指定自定义函数,用于创建所选对象的实例。
// 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;
过滤类型的方法。
// 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 窗口中只能场景对象,限制拖拽的资源类型。
// 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 是否可折叠。
// 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
绘制二维数组。
-
单元格绘制。
-
string HorizontalTitle
水平标题。
-
bool SquareCells
如果为 true,则每行的高度将与第一个单元格的宽度相同。
-
// 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
}
-
表格绘制
-
bool IsReadOnly
如果为 true,则插入、删除和拖动列和行将不可用。但单元格本身仍将是可修改的。
如果要禁用所有内容,可以使用 ReadOnly 属性。
-
string VerticalTitle
垂直标题。
-
// 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];
}
-
图形绘制
-
string DrawElementMethod
覆盖绘制每个单元格的方式。
输入参数:
Rect rect, T value
输出:
T
-
bool ResizableColumns = true
列是否可调整大小。
-
RowHeight
行高,0 表示默认高度。
-
bool Transpose
如果为 true,则表的行/列颠倒绘制(C# 初始化顺序)。
-
// 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,其中一个打开,其他的开关组都将折叠显示。
// 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 窗口中显示的标题名称。
// 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;}
}