Custom Property - rmfandyplayz/UnityUIAnimationTools GitHub Wiki
For anything the other step types don't cover: a score counting up, dialogue typing itself out, an Image's fill, a slider, a scroll position, or a value on one of your own scripts.
▼ AFTER Score (TextMeshProUGUI.text as number) 1s Out Quad
Start [AFTER PREVIOUS]
Type Custom Property
Game Object Score
Target Path
Property TextMeshProUGUI.text as number ▾
Duration 1
Delay 0
Ease Out Quad
FROM [Absolute] 0
To [Absolute] 1500
Format N0
- Set Type to
Custom Property. - Point it at an object: the Game Object slot, a Target Path, or neither for the player's own object.
- Open Property. It lists everything on that object that can be animated, grouped by component, the same way a button's On Click dropdown does (
Image/float fillAmount). - Pick one, and From and To change to match it.
Everything else works as on any step: From/To, the modes, Duration, Delay, Ease, custom curves, Play At Custom FPS, mirroring and copy/paste.
What's listed: anything public on a component that's a whole number (int), a decimal number (float), a Vector2, Vector3, Color or text (string), as long as it can be both read and changed. Your own scripts work too: a public float Health { get; set; } shows up under its component.
Text can move in two ways, so each text property is listed twice:
| Entry | Does |
|---|---|
string text (typewriter) |
Types the text out, letter by letter, replacing From with To. Rich-text tags like <b> are never shown half-written. |
string text (as number) |
Counts a number from From to To and shows it in the text, using Format. A score counter. |
Format controls how the number looks:
| Format | Shows |
|---|---|
0 |
Whole numbers: 1500
|
0.0 |
One decimal place: 1500.0
|
N0 |
Thousands separators: 1,500
|
00 |
At least two digits: 07
|
With From off, a counter counts on from the number already showing, as long as the text is only a number. Score: 120 reads as 0, so put the label in a separate text object.
Baseline on text means "the resting text, plus what you type added onto the end". So To: Baseline with nothing typed is whatever the text said at rest. Current isn't offered for text.
Give the step its value from code just before playing. See Setting From and To from code.
anim.SetTo("CountUp", 0, score); // counter
anim.SetTo("Say", 0, line); // typewriter, with FROM [Absolute] ""Two other ways to type text out:
-
FROM [Absolute] ""→To [Baseline] ""types out the resting text. Set the text, callplayer.CaptureBaseline()so that becomes the resting text, then play. - Or pick
int maxVisibleCharacterson the TextMeshPro and animate it from0to at least the length of your longest line. Words never jump to the next line mid-word this way, but the typing speed then depends on the line's length.
| Property type | From / To | Notes |
|---|---|---|
float |
a number | |
int |
a whole number | Rounded every frame, so a counter on an int ticks cleanly |
Vector2 |
X / Y | |
Vector3 |
X / Y / Z | |
Color |
a colour | |
string (typewriter) |
text |
Absolute and Baseline only |
string (as number) |
a number | Plus Format |
- Renaming the component or property in code breaks the step. It shows a ⚠ in the Inspector, and in the game it warns once and is skipped. Pick the property again.
-
The property really changes, even in the edit-mode preview. Animating
Slider.valuefires the slider'sOn Value Changedevery frame. Listeners set to Runtime Only (the default) stay quiet outside play mode, but anything in your own scripts' setters runs. - In an Animation Set, set Preview On first. Picking a property needs a real object to list from. Once it's picked, the step keeps everything it needs.
- If the object has two components of the same type, the first one is used.
- No Snapping (use an
intproperty for whole numbers), no movement path, and not drawn by the Scene gizmos.
Under the hood
- Stored by name: the step stores the component's full type name, the member's name, and what kind of value it is. The component is found by matching type names against what's actually on the object, so moving a script to another assembly doesn't break a step. A member whose type changed is caught and skipped, never guessed at.
-
Left out of the list: read-only,
[Obsolete], static and indexer members, and the ones every component inherits (name,tag,enabled), which would otherwise appear under every component. A name re-declared withnew, or an override that only replaces the getter, binds to the declaration that has a setter. -
Fast at runtime: a property's getter and setter are bound once at
AwakewithDelegate.CreateDelegate, the same way UnityEvent binds a listener, so there's no reflection or boxing per frame. A public field goes through reflection each frame, which is slower but irrelevant at UI scale. - The Inspector never calls a getter (a getter is arbitrary code, and the Inspector redraws constantly). Only a click on the record button reads one. Getters and setters that throw are caught, warned about once, and that step is skipped, so one bad member can't leave the player or the preview half-done.
-
Counted-number text keeps two resting values: the parsed number (what
Baselinemeasures from) and the original text (what the preview restores). So the preview puts backScore: 120, not0. A bad Format falls back to the plain number rather than throwing every frame. -
Why no
Currentfor text: DOTween can append to text, but a mirrored copy couldn't take appended characters back off. -
IL2CPP builds with Managed Stripping above Minimal can strip a property setter that nothing but this tool calls. If one goes missing in a build only, preserve it with a
link.xml.