-
-
Notifications
You must be signed in to change notification settings - Fork 245
Attributes
AutoProperty — Assign fields automatically
ButtonMethod — Display button in inspector
CharactersRange — Filter string field by the set of characters
ConditionalField — Conditionally display property in inspector, based on some other property value
ConstantsSelection — Popup of const, readonly or static fields and properties
DefinedValues — Display Dropdown with predefined values
DisplayInspector — Display one inspector inside of another
Foldout — Group your fields in inspector
InitializationField — Field that is not editable in playmode
Tag, Layer, SpriteLayer — Dropdown with Tags, Layers or SpriteLayers
MinMaxRange, RangedFloat and RangedInt — Ranged sliders
MaxValue, MinValue and PositiveValueOnly — Validation for numbers and vectors
MustBeAssigned — Automatically checks if field is assigned
OverrideLabel — Change visible in Inspector field name
ReadOnly — Draw property with disabled GUI
RegexString — Filter string field by the Regular Expression
RequireTag and RequireLayer — Automatically set Tag and Layer
Scene — Friendly way to keep Scene name as a string. See also SceneReference type
SearchableEnum — Nice UI for enums with lots of elements
Separator — Draw separator with or without title
Automatically assign property on Scene Save event (works best with AutoSave Feature!)
When used in Prefabs will be checked on Prefab Stage Opened and Saved
Bind and cache components and arrays of components.
Allows to save some code time and gain bits of performance with absence of GetComponent calls
You'll get error message if there is no matching components.
Several modes are supported:
- AutoPropertyMode.Children is default, similar to GetComponentsInChildren()
- AutoPropertyMode.Parent — similar to GetComponentsInParent()
- AutoPropertyMode.Scene — similar to Object.FindObjectsOfType()
- AutoPropertyMode.Asset will search for this asset type in Assets folder
- AutoPropertyMode.Any works as "Scene + Asset" modes
[AutoProperty(AutoPropertyMode.Parent)] public Rigidbody AbsentRB;
// Assuming AudioManager is "ScriptableObject Singleton" in your project
[AutoProperty(AutoPropertyMode.Asset)] public AudioManager AudioManager;
[AutoProperty] public Collider[] ChildColliders;
[AutoProperty] public GuidComponent[] ChildGuids;
Another use-case for this attribute:
// Automatically updated collection of types on the scene, how cool is that 😁?
[AutoProperty(AutoPropertyMode.Scene)] public Camera[] AllCamerasOnScene;
You may apply this attribute to any method and this will appear in inspector as a button.
If this method returns anything, result will be logged.
public Collider[] Colliders;
#if UNITY_EDITOR // conditional compilation is not mandatory
[ButtonMethod]
private string CollectColliders()
{
Colliders = FindObjectsOfType<Collider>();
return Colliders.Length + " Colliders found on scene, cached";
}
#endif
See also RegexString Attribute
Allows to restrict the string field by the set of characters
Optionally, you can use several Modes:
// By default, only characters in range will be allowed
CharactersRangeMode.Allow
// Characters in range will be removed from the string
CharactersRangeMode.Disallow
// Highlight the field if any of the specified characters were fould
CharactersRangeMode.WarningIfAny
// Highlight the field if some characters in string are not the characters from specified range
CharactersRangeMode.WarningIfNotMatch
Also with the third parameter you can disable "Ignore Case" option
[CharactersRange("0123456789.-")]
public string DigitsOnly;
[CharactersRange("1234567890ABCDEF", CharacterRangeMode.WarningIfNotMatch)]
public string HexValue;
Thanks to tonygiang for this Attribute 🤓!
This attribute allows you to conditionally hide/show fields in inspector, based on some other field.
You may also use ReadOnlyAttribute to make field disabled instead of hiding it
By default ConditionalField checks if "fieldToCheck" value is not null, not 0 and not empty.
Basically it means "if something assigned to field A, show field B".
Second parameter is "inverse", well.. to inverse the result 🙂 This one is optional
You may also specify "compareValues". Very handy to check for specific enum value for example!
[Separator("GameObject / Component")]
public Transform Target;
[ConditionalField(nameof(Target))] public float TargetSpeed;
[ConditionalField(nameof(Target), inverse:true)] public float Speed;
[Separator("Bool")]
public bool Teleport;
[ConditionalField(nameof(Teleport))] public float TeleportationDelay;
[Separator("String")]
public string Hello;
[ConditionalField(nameof(Hello), false, "Hello")] public string HelloWorld = "World! :)";
[ConditionalField(nameof(Hello))] public string HelloHint = "Print \"Hello\"!";
[Separator("Enum")]
public AIState State = AIState.None;
[ConditionalField(nameof(State), false, AIState.Walk)] public float WalkSpeed;
[ConditionalField(nameof(State), false, AIState.Idle)] public float IdleTime;
Thanks to Kaynn-Cahya you may also specify several compare values!🤓:
public AIState State = AIState.None;
[ConditionalField(nameof(State), false, AIState.Walk, AIState.Run)] public float Speed;
There is a natural limitation in Unity preventing usage of attribute drawers (such as ConditionalField) on arrays.
To handle such cases CollectionWrapper was made.
public bool ShowWrappedCollection;
[ConditionalField(nameof(ShowWrappedCollection))]
public GOCollection WrappedCollection;
[Serializable]
public class GOCollection : CollectionWrapper<GameObject> {}
Since Unity 2020.1 you may use generics directly but field name won't be shown in inspector 🙄
[ConditionalField(nameof(ShowWrappedCollection))]
public CollectionWrapper<GameObject> WrappedCollection;
Allows to display a popup of const, readonly, static fields and properties defined in specified script:
[ConstantsSelection(typeof(PresetLayers))] public string DefaultLayer = "Default";
[ConstantsSelection(typeof(Vector3))] public Vector3 UnityDefaultVectors;
[ConstantsSelection(typeof(Color))] public Color UnityDefaultColors;
public class PresetLayers
{
public const string Interactive = "Interactive";
public const string Obstacle = "Obstacle";
}
[DefinedValues(1, 3, 5)]
public int AgentHeight;
Displays one inspector inside of another. It's handy if you'd like to store some settings in scriptable objects.
[DisplayInspector(displayScriptField:false)] to hide object field once assigned (useful for "single instance" settings)
[CreateAssetMenu]
public class AgentAIContextSettings : ScriptableObject
{
public bool WanderAround;
public float WanderDistance = 5;
}
[DisplayInspector]
public AgentAIContextSettings Settings;
Set displayScriptField to false (by default it's true) to hide property field once
[DisplayInspector(displayScriptField:false)]
Put attribute before variable and you are done!
public class Player : MonoBehaviour
{
[Foldout("Setup")] public Transform selfTransform;
[Foldout("Data")] public int HP;
[Foldout("Data")] public int AT;
}
You don't need to write [Foldout] attribute each time! Instead, you can add "true" bool check after naming to put all properties to the specified group:
public class Player : MonoBehaviour
{
[Foldout("DATA OBJECT", true)]
public int hp;
public int attack = 20;
[SerializeField]
private GameObject self;
[Foldout("DATA ATTACK")]
public int AT;
}
Note, that Foldout need to be part of MonoBehaviour or ScriptableObject, it is not intended to work in Serializable classes
Thanks to PixeyeHQ for this attribute! 🤓
Field will be not editable at playmode:
[InitializationField] public int MaxHP;
[ReadOnly] public int CurrentHP;
69 in this example is pure random, I swear!
[Tag]
public string Tag;
[Layer]
public int Layer;
[SpriteLayerAttribute]
public int SortingLayer;
by Richard Fine
public class RandomisedHealth : MonoBehaviour
{
[MinMaxRange(80, 120)]
// Will be set to 90-100 by default in inspector
public RangedInt Health = new RangedInt(90, 100);
[MinMaxRange(0, 1)]
public RangedFloat Raito;
}
These attributes works with numbers and vectors
[PositiveValueOnly]
public Vector2 ScanRange;
[PositiveValueOnly]
public float ChaseSpeed;
Previously I used a lot of Debug.Assert() in Awake to ensure that all desired values are assigned through inspector. Now I just use MustBeAssigned.
It triggers on value types with default values, null refs, empty arrays and strings
[MustBeAssigned]
public MonoBehaviour MyScript;
[MustBeAssigned]
public float MyFloat;
Change visible in Inspector field name:
OverrideLabel("GUID")]
public string InternalGUID;
originally made to fix serialized properties naming issue
Disallow field edit in Inspector.
Might also work just like ConditionalAttribute to make field disabled, based on some other field value.
public float InitialHealth = 100;
[ReadOnly]
public float CurrentHealth;
See also CharactersRange Attribute
Allows to apply Regular Expression rule to the string field
Optionally, you can use several Modes:
// By default, keep only parts of the string that Match the Expression
RegexStringMode.Match
// Remove from the string parts that not match the Expression
RegexStringMode.Replace
// Highlight the field if any of the parts of the string matching the Expression
RegexStringMode.WarningIfMatch
// Highlight the field if some parts of the string not matching the Expression
RegexStringMode.WarningIfNotMatch
Also with the third parameter you can specify RegexOprions for validator
[RegexString(MyRegex.FloatingNumber)]
public string MatchDigit;
[RegexString(@"\d+", RegexStringMode.Replace)]
public string WithoutNumbers;
[RegexString("[a-zA-Z]+", RegexStringMode.WarningIfNotMatch)]
public string Name;
[RegexString(MyRegex.Email, RegexStringMode.WarningIfNotMatch)]
public string Email;
[RequireLayer("Interactive")]
[RequireTag("Acquirable")]
public class PickupItem : MonoBehaviour { ... }
This attributes will set layer and tag of GameObject with such script on playmode.
Changes will persist when you will exit playmode
You may use layer index instead of a name
only works on objects present on scene initially, won't work on objects instantiated during playmode
by Anton
[Scene]
public string SceneA;
Consider to use SceneReference type instead as it keeps scene reference if Scene is renamed
by incredible Ryan Hipple
Decorative separator. May be with or without title