SerializedProperty Extensions
Write editor properties in one line — and reach the actual C# field the property shows in the Inspector.
Quick start
| Before — Unity API | After — FastTools |
|---|---|
| |
Writing values
| Before — Unity API | After — FastTools |
|---|---|
| |
| |
| |
Supported types
| Values | Setters |
|---|---|
| Numbers | SetInt, SetUint, SetLong, SetUlong, SetFloat, SetDouble |
| Text, bool and hash | SetString, SetBool, SetHash128 |
| Vectors | SetVector2, SetVector2Int, SetVector3, SetVector3Int, SetVector4, SetQuaternion |
| Areas | SetRect, SetRectInt, SetBounds, SetBoundsInt |
| Unity types | SetColor, SetGradient, SetAnimationCurve |
| Object IDs | SetEntityId |
Each has a SetValue overload: SetValue(42) calls SetInt, so the argument type must match the field type.
Enums, arrays and references
| Unity | FastTools |
|---|---|
enumValueIndex = 1 | SetEnumIndex(1) |
enumValueFlag = flags | SetEnumFlag(flags) |
arraySize = 5 | SetArraySize(5) |
arraySize += n | AddArraySize(n = 1) |
arraySize -= n | RemoveArraySize(n = 1) |
managedReferenceValue = value | SetManagedReference(value) |
objectReferenceValue = value | SetObjectReference(value) |
boxedValue = value | SetBoxed(value) |
exposedReferenceValue = value | SetExposedReference(value) |
Update() and Apply…()
| Unity | FastTools |
|---|---|
serializedObject.Update() | Update() |
serializedObject.UpdateIfRequiredOrScript() | UpdateIfRequiredOrScript() |
serializedObject.ApplyModifiedProperties() | ApplyModifiedProperties() |
serializedObject.ApplyModifiedPropertiesWithoutUndo() | ApplyModifiedPropertiesWithoutUndo() |
They are called on the property and, like every setter, return it.
The C# field from the Inspector
Three methods find the C# field the property shows in the Inspector: its type, the field itself and the object that holds it.
public class AbilityBook : MonoBehaviour
{
[SerializeField]
private List<Ability> _abilities = new() { new Ability() };
[SerializeReference]
private IAbilityEffect _effect = new BurnEffect();
}
[Serializable]
public class Ability { public string Name = "Fireball"; }
[Serializable]
public class BurnEffect : IAbilityEffect { public float Damage = 5f; }
| Property path | GetPropertyType() | GetFieldInfo() | GetDeclaringInstance() |
|---|---|---|---|
_abilities | List<Ability> | AbilityBook._abilities | the AbilityBook |
_abilities[0] | Ability | AbilityBook._abilities | the AbilityBook |
_abilities[0].Name | string | Ability.Name | the Ability at index 0 |
_effect | IAbilityEffect | AbilityBook._effect | the AbilityBook |
_effect.Damage | float | BurnEffect.Damage | the BurnEffect instance |
- if the field is not found,
GetPropertyType()andGetFieldInfo()returnnull, andGetDeclaringInstance()does only when the owning object is not found; - the methods read only the first target object and only applied values.
When the field's owner is a struct, GetDeclaringInstance() returns a boxed copy. Changes to that copy never reach the original; write values through the SerializedProperty instead.
Member name and drawing checks
| Property path | GetMemberName() | IsArrayElement() | HasFoldout() |
|---|---|---|---|
_abilities[0] | "_abilities" | true | true |
_abilities[0].Name | "Name" | false | false |
_effect | "_effect" | false | false |
HasFoldout() returns true for a plain compound field with visible children, so it can differ from the Inspector: a [SerializeReference] field gets a foldout in the Inspector but false here, and custom PropertyDrawers are not taken into account.
Persistent()
Persistent() returns a copy of the property on its own SerializedObject, so it can be used later, for example in EditorApplication.delayCall.
| Before — Unity API | After — FastTools |
|---|---|
| |
- the copy belongs to the caller: dispose it together with its
serializedObject; - unapplied writes of the source property do not reach the copy;
- if the property is missing on the targets, the method returns
null.
var independent = manaCost.Persistent();
if (independent == null) return;
EditorApplication.delayCall += () =>
{
using (independent.serializedObject)
using (independent)
independent.Update().SetIntAndApply(42);
};
Package sample
In EditorTools, the Halve cooldown, +5 MP button writes two properties with SetFloat and SetIntAndApply.