文章目录
- 1 说明
- 2 验证特性
- 2.1 AssetsOnly / SceneObjectsOnly
- 2.2 ChildGameObjectsOnly
- 2.3 DisallowModificationsIn
- 2.4 FilePath
- 2.5 FolderPath
- 2.6 MaxValue / MinValue
- 2.7 MinMaxSlider
- 2.8 PropertyRange
- 2.9 Required
- 2.10 RequiredIn
- 2.11 RequiredListLength
- 2.12 ValidateInput
1 说明
本文介绍 Odin Inspector 插件中有关验证特性的使用方法。
2 验证特性
2.1 AssetsOnly / 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.2 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.3 DisallowModificationsIn
当该对象所在的脚本挂载在何种预制体上,其修饰的对象将被禁用 / 灰色显示。
PrefabKind prefabKind
预制体的种类。
None
所有预制体,都不满足条件。
InstanceInScene
场景中的预制体实例。
InstanceInPrefab
嵌套在其他预制体中的预制件实例。
Regular
常规预制体。
Variant
预制体资产。
NonPrefabInstance
非预制体或场景中的游戏对象实例。
PrefabInstance = InstanceInPrefab | InstanceInScene
常规预制体的实例,以及场景中或嵌套在其他预制体中的预制体。
PrefabAsset = Variant | Regular
常规预制体和预制体资产。
PrefabInstanceAndNonPrefabInstance = PrefabInstance | NonPrefabInstance
预制体以及非预制实例。
All = PrefabInstanceAndNonPrefabInstance | PrefabAsset
所有预制体。
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;public class Test : MonoBehaviour
{[DisallowModificationsIn(PrefabKind.PrefabAsset)]public GameObject o;
}
2.4 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.5 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.6 MaxValue / MinValue
在 Inspector 窗口中对象能够被设置的最小 / 大值。超过该范围则会有错误提示。
double maxValue/minValue
最大 / 小值。
string Expression
用于解析最大 / 小值的字符串。可以是字段、属性、方法名或表达式。
// MinMaxValueValueExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class MinMaxValueValueExamplesComponent : MonoBehaviour
{// Ints[Title("Int")][MinValue(0)]public int IntMinValue0;[MaxValue(0)]public int IntMaxValue0;// Floats[Title("Float")][MinValue(0)]public float FloatMinValue0;[MaxValue(0)]public float FloatMaxValue0;// Vectors[Title("Vectors")][MinValue(0)]public Vector3 Vector3MinValue0;[MaxValue(0)]public Vector3 Vector3MaxValue0;
}
2.7 MinMaxSlider
将 Vector2 向量表示为 [min, max] 区间,并在 Inspector 窗口中以滑动条方式显示。其中,x 为最小值,y 为最大值。
float minValue/maxValue
最小 / 大值。
string minValueGetter/maxValueGetter
获取最小 / 大值的方法名称。
string minMaxValueGetter
获取最小、大值对的方法名称。
bool showFields = false
是否显示对象名称。
// MinMaxSliderExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class MinMaxSliderExamplesComponent : MonoBehaviour
{[MinMaxSlider(-10, 10)]public Vector2 MinMaxValueSlider = new Vector2(-7, -2);[MinMaxSlider(-10, 10, true)]public Vector2 WithFields = new Vector2(-3, 4);[InfoBox("You can also assign the min max values dynamically by referring to members.")][MinMaxSlider("DynamicRange", true)]public Vector2 DynamicMinMax = new Vector2(25, 50);[MinMaxSlider("Min", 10f, true)]public Vector2 DynamicMin = new Vector2(2, 7);[InfoBox("You can also use attribute expressions with the @ symbol.")][MinMaxSlider("@DynamicRange.x", "@DynamicRange.y * 10f", true)]public Vector2 Expressive = new Vector2(0, 450);public Vector2 DynamicRange = new Vector2(0, 50);public float Min { get { return this.DynamicRange.x; } }public float Max { get { return this.DynamicRange.y; } }
}
2.8 PropertyRange
创建滑块控件,将属性的值设置在指定范围之间。
double min/max
最小 / 大值。
string minGetter/maxGetter
获取最小、大值的方法名称。
// PropertyRangeExampleComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class PropertyRangeExampleComponent : MonoBehaviour
{[Range(0, 10)]public int Field = 2;[InfoBox("Odin's PropertyRange attribute is similar to Unity's Range attribute, but also works on properties.")][ShowInInspector, PropertyRange(0, 10)]public int Property { get; set; }[InfoBox("You can also reference member for either or both min and max values.")][PropertyRange(0, "Max"), PropertyOrder(3)]public int Dynamic = 6;[PropertyOrder(4)]public int Max = 100;
}
2.9 Required
如果对象没有被关联,则显示错误信息。
string errorMessage
显示信息。
InfoMessageType messageType
信息类型。
// RequiredExamplesComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;public class RequiredExamplesComponent : MonoBehaviour
{[Required]public GameObject MyGameObject;[Required("Custom error message.")]public Rigidbody MyRigidbody;[InfoBox("Use $ to indicate a member string as message.")][Required("$DynamicMessage")]public GameObject GameObject;public string DynamicMessage = "Dynamic error message";
}
2.10 RequiredIn
当该对象所在的脚本挂载在何种预制体上,其修饰的对象必须被关联,否则显示错误信息。
string errorMessage
显示信息。
PrefabKind prefabKind
预制体的种类。
None
所有预制体,都不满足条件。
InstanceInScene
场景中的预制体实例。
InstanceInPrefab
嵌套在其他预制体中的预制件实例。
Regular
常规预制体。
Variant
预制体资产。
NonPrefabInstance
非预制体或场景中的游戏对象实例。
PrefabInstance = InstanceInPrefab | InstanceInScene
常规预制体的实例,以及场景中或嵌套在其他预制体中的预制体。
PrefabAsset = Variant | Regular
常规预制体和预制体资产。
PrefabInstanceAndNonPrefabInstance = PrefabInstance | NonPrefabInstance
预制体以及非预制实例。
All = PrefabInstanceAndNonPrefabInstance | PrefabAsset
所有预制体。
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;public class Test : MonoBehaviour
{[RequiredIn(PrefabKind.PrefabAsset)]public GameObject o;
}
2.11 RequiredListLength
将 List 限制为包含指定数量的元素。
int minLength/maxLength
最小 / 大长度。
string minLengthGetter/maxLengthGetter
用于获取集合最小 / 大长度的 C# 表达式,例如“@this.otherList.Count”。
如果设置了 MinLength,则当 MinLengthGetter 返回 null 时,MinLength 将作为回退。
string fixedLengthGetter
用于获取集合长度的 C# 表达式。
PrefabKind PrefabKind
长度限制应用于哪种预制体上。
// RequiredListLengthExamplesComponent.csusing System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;public class RequiredListLengthExamplesComponent : MonoBehaviour
{[RequiredListLength(10)]public int[] fixedLength;[RequiredListLength(1, null)]public int[] minLength;[RequiredListLength(null, 10, PrefabKind = PrefabKind.InstanceInScene)]public List<int> maxLength;[RequiredListLength(3, 10)]public List<int> minAndMaxLength;public int SomeNumber;[RequiredListLength("@this.SomeNumber")] public List<GameObject> matchLengthOfOther;[RequiredListLength("@this.SomeNumber", null)]public int[] minLengthExpression;[RequiredListLength(null, "@this.SomeNumber")]public List<int> maxLengthExpression;
}
2.12 ValidateInput
允许检查 Inspector 窗口中拖拽关联值是否正确。
string condition
判断是否正确的方法。
string defaultMessage
显示信息。
InfoMessageType messageType
信息类型。
// ValidateInputExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.OdinInspector.Editor.Examples;
#endifpublic class ValidateInputExamplesComponent : MonoBehaviour
{
#if UNITY_EDITOR // MyScriptyScriptableObject is an example type and only exists in the editor[HideLabel][Title("Default message", "You can just provide a default message that is always used")][ValidateInput("MustBeNull", "This field should be null.")]public MyScriptyScriptableObject DefaultMessage;
#endif[Space(12), HideLabel][Title("Dynamic message", "Or the validation method can dynamically provide a custom message")][ValidateInput("HasMeshRendererDynamicMessage", "Prefab must have a MeshRenderer component")]public GameObject DynamicMessage;[Space(12), HideLabel][Title("Dynamic message type", "The validation method can also control the type of the message")][ValidateInput("HasMeshRendererDynamicMessageAndType", "Prefab must have a MeshRenderer component")]public GameObject DynamicMessageAndType;[Space(8), HideLabel][InfoBox("Change GameObject value to update message type", InfoMessageType.None)]public InfoMessageType MessageType;[Space(12), HideLabel][Title("Dynamic default message", "Use $ to indicate a member string as default message")][ValidateInput("AlwaysFalse", "$Message", InfoMessageType.Warning)]public string Message = "Dynamic ValidateInput message";#if UNITY_EDITOR // Editor-related code must be excluded from buildsprivate bool AlwaysFalse(string value) {return false;}private bool MustBeNull(MyScriptyScriptableObject scripty) {return scripty == null;}private bool HasMeshRendererDefaultMessage(GameObject gameObject) {if (gameObject == null) return true;return gameObject.GetComponentInChildren<MeshRenderer>() != null;}private bool HasMeshRendererDynamicMessage(GameObject gameObject, ref string errorMessage) {if (gameObject == null) return true;if (gameObject.GetComponentInChildren<MeshRenderer>() == null) {// If errorMessage is left as null, the default error message from the attribute will be usederrorMessage = "\"" + gameObject.name + "\" must have a MeshRenderer component";return false;}return true;}private bool HasMeshRendererDynamicMessageAndType(GameObject gameObject, ref string errorMessage, ref InfoMessageType? messageType) {if (gameObject == null) return true;if (gameObject.GetComponentInChildren<MeshRenderer>() == null) {// If errorMessage is left as null, the default error message from the attribute will be usederrorMessage = "\"" + gameObject.name + "\" should have a MeshRenderer component";// If messageType is left as null, the default message type from the attribute will be usedmessageType = this.MessageType;return false;}return true;}
#endif
}