SaintsField Documentation
repository·master·Indexed 20 days ago
https://github.com/tylertemp/saintsfieldA Unity plugin (version 5.25.5) for enhancing the Inspector and data serialization. It provides advanced attributes for grouping fields, serializing complex types like dictionaries and interfaces, and customizing the developer experience with tools such as LabelText, InfoBoxes, and separators.
What's inside SaintsField
- SaintsField is a Unity extension tool designed to enhance the Unity Inspector and improve data serialization. It provides developers with advanced tools for managing how data is displayed and stored within the Unity Editor.
Explore SaintsField General Attributes
masterSaintsField provides a wide range of attributes to customize the Unity Inspector. These attributes are categorized by their functional purpose:
- Label & Text: Control how labels and text are displayed (e.g.,
LabelText,AboveText,OverlayText,Separator). - Button: Add interactive buttons to the inspector (e.g.,
Button,PostFieldButton). - Game Related: Link inspector fields to Unity engine concepts (e.g.,
Layer,Scene,Tag,InputAxis,ShaderParam). - Toggle & Switch: Create visual toggles for various types (e.g.,
GameObjectActive,SpriteToggle,MaterialToggle). - Data Editor: Enhance data visualization and selection (e.g.,
Expandable,ReferencePicker,Table,ShowInInspector). - Numerical: Specialized controls for numbers (e.g.,
Rate,PropRange,MinMaxSlider,ProgressBar). - Animation: Control animation parameters (e.g.,
AnimatorParam,AnimatorState,CurveRange). - Auto Getter: Automatically fetch components or objects (e.g.,
GetComponent,GetInScene,GetMainCamera,AddComponent). - Validate & Restrict: Enforce rules on field values (e.g.,
ReadOnly,ShowIf,RequiredIf,MinValue,ArraySize). - Miscellaneous: Various UI enhancements (e.g.,
Dropdown,ValueButtons,ColorPalette,Searchable,DateTime).
- Label & Text: Control how labels and text are displayed (e.g.,
Serialize long/ulong based Enums
masterUnity does not support enums with a
longorulongbase type. You can bypass this limitation by applying[SaintsSerialized]to the enum field.Requirements:
- The containing
MonoBehaviour/ScriptableObjectmust bepartial. - The enum field must have the
[SaintsSerialized]attribute. - If the enum is used inside a normal class/struct, that class/struct must also be
partial.
EnumToggleButtonsis fully supported with these enums.public partial class MyBehavior: MonoBehaviour { [Flags] public enum TestULongEnum: ulong { None = 0, First = 1, Second = 1 << 1, } [SaintsSerialized] public TestULongEnum ULongEnumPub; [SaintsSerialized, EnumToggleButtons] public TestULongEnum ULongEnumPubBtns; }- The containing
Use AI Navigation attributes for Unity NavMesh
masterSaintsField provides tools for Unity AI Navigation (
NavMesh) in theSaintsField.AiNavigationnamespace. These are only active if theAI Navigationpackage is installed.To disable these components, add the macro
SAINTSFIELD_AI_NAVIGATION_DISABLEDto your project.Available Attributes:
[NavMeshAreaMask]: A picker to select aNavMesharea bit mask for an integer field.[NavMeshArea]: A picker to select aNavMesharea for string or integer fields, with support for bit masks or single area values.
using SaintsField.AiNavigation; [NavMeshAreaMask] public int areaMask; [NavMeshArea] public int areaSingleMask;Understand EMode values
masterThe
EModeenum is used to determine the current context of the Unity Editor or the target object:EMode.Edit: Editor is not playing.EMode.Play: Editor is playing.EMode.InstanceInScene: Target is a prefab placed in a scene.EMode.InstanceInPrefab: Target is inside a prefab (but not the root).EMode.Regular: Target is at the top root of a prefab.EMode.Variant: Target is a variant prefab root.EMode.NonPrefabInstance: Target is not a prefab.EMode.PrefabInstance: Alias forInstanceInPrefab | InstanceInScene.EMode.PrefabAsset: Alias forVariant | Regular.
Use Unity-specific axes for resource traversal
masterIn addition to standard axes like
ancestor::,ancestor-or-self::,parent::, andparent-or-self::, Saints XPath provides specialized axes to target Unity-specific resources:ancestor-inside-prefab::: Traverses ancestors within a prefab boundary.ancestor-or-self-inside-prefab::: Traverses ancestors or self within a prefab boundary.parent-inside-prefab::: Traverses the parent within a prefab boundary.parent-or-self-inside-prefab::: Traverses the parent or self within a prefab boundary.scene::: Targets the scene root node.prefab::: Targets the prefab root node.resources::: Targets resources.asset::: TargetsAssetDatabaseresources.
Use Spine attributes for robust references
masterSaintsField provides a suite of attributes in the
SaintsField.Spinenamespace that improve upon standard Unity Spine attributes. These attributes support searching, are compatible with theAuto Validatortool, and work with Unity's default right-click context menu.Most attributes allow you to specify a
skeletonTarget(aSkeletonData,SkeletonRenderer, component, or GameObject with aSkeletonRenderer) to define the source of the data. If null, it defaults toGetComponent<SkeletonRenderer>()on the current object.using SaintsField.Spine; // Example of targeting a specific field as the source public SkeletonAnimation _spine; [SpineAnimationPicker(nameof(_spine))] private AnimationReferenceAsset animationRef;Inspect Interfaces and Dictionaries in the Inspector
masterSaintsField allows you to inspect interfaces and collections like
Dictionary<TKey, TValue>orIReadOnlyDictionary<TKey, TValue>directly in the Unity Inspector using the[ShowInInspector]attribute. For interfaces, the inspector will automatically show an object picker or a field editor depending on whether the underlying type is aUnityObjector a general class/struct.public class GeneralDummyClass: IDummy { public string GetComment() => "DummyClass"; public int MyInt { get; set; } public int GenDumInt; public string GenDumString; } [ShowInInspector] private static IDummy _dummy; [Button] private void DebugDummy() => Debug.Log(_dummy);Serialize Dictionary<,> and HashSet<>
masterYou can serialize
Dictionary<,>andHashSet<>directly by applying[SaintsSerialized].- Dictionaries: Internally uses
SaintsDictionaryfor serialization. This supports interfaces as keys or values and can be nested inside arrays or lists.- Note for Callbacks: If using
[OnValueChanged], the callback parameter must be typed asIDictionary<,>orSaintsDictionary<,>.
- Note for Callbacks: If using
- HashSets: Supports serializable types, abstract classes/structs, and interface types as element types.
Requirement: The containing class/struct must be
partial.public partial class SerDictionaryExample : MonoBehaviour { // Dictionary support [SaintsSerialized] public Dictionary<int, IInterface1> _dictInterface; [SaintsSerialized] private List<Dictionary<IInterface1, IInterface1>> _dictInterfaceLis; // Dictionary OnValueChanged callback requirement [SaintsSerialized, OnValueChanged(nameof(ChangedWatcher))] private Dictionary<string, int> _myDictionary; private void ChangedWatcher(IDictionary<string, int> dic) => Debug.Log(dic); // HashSet support [SaintsSerialized] public HashSet<string> stringHashSet; [SaintsSerialized] public HashSet<IInterface1> refHashSet; }- Dictionaries: Internally uses
Implement custom search logic for lists
masterTo implement custom search logic, provide a method name to the
extraSearchoroverrideSearchparameters of[ListDrawerSettings].Supported Method Signatures:
bool CustomSearch(T item, int index, IReadOnlyList<ListSearchToken> searchToken)bool CustomSearch(T item, IReadOnlyList<ListSearchToken> searchToken)bool CustomSearch(int index, IReadOnlyList<ListSearchToken> searchToken)
ListSearchToken Structure:
ListSearchType Type: The filter type (IncludeorExclude).string Token: The search string used for filtering.
[Serializable] public struct Weapon { public WeaponType weaponType; public string description; } private bool ExtraSearch(Weapon weapon, int _, IReadOnlyList<ListSearchToken> tokens) { string searchName = new Dictionary<WeaponType, string> { { WeaponType.Arch , "弓箭 双手" }, { WeaponType.Sword , "刀剑 单手" }, { WeaponType.Hammer, "大锤 双手" }, }[weapon.weaponType]; return RuntimeUtil.SimpleSearch(searchName, tokens); } [ListDrawerSettings(extraSearch: nameof(ExtraSearch))] public Weapon[] weapons;Create nested and grouped items in Dropdowns
masterYou can create hierarchical dropdown menus by nesting
Dropdown<T>objects within each other. ADropdown<T>item can either be a direct value or a group containingIEnumerable<Dropdown<T>> children. You can also insert separators usingDropdown<T>.Separator().[Dropdown(nameof(AdvDropdown))] public int drops; public Dropdown<int> AdvDropdown() { return new Dropdown<int>("First Half") { new Dropdown<int>("Monday", 1, icon: "eye.png"), new Dropdown<int>("Tuesday", 2), }; }Understand the Saints XPath syntax and structure
masterSaints XPath is a subset of the standard XPath language designed for Unity. It uses a step-based structure to traverse nodes.
Basic Structure:
step/step/step/...A
stepfollows the pattern:axisname::nodetest[predicate]Key Syntax Rules:
- Axes and Attributes: You can select attributes using
@. For example,name@attributeis valid, but you cannot mix::and@in the same segment (e.g.,ancestor::name@attris invalid; useancestor::name/@attrinstead). - Predicates: Predicates are enclosed in square brackets
[]. They can filter by attributes using@, but they do not select the attribute itself. - Predicates Requirement: There must be a space before the predicate (e.g.,
node [@attr=val]). - Limitations: Complex XPath features like forward/backward assertions (e.g.,
name[ancestor::note()[@attr=1]]) are not supported.
- Axes and Attributes: You can select attributes using