UGTK / Toolkit / Ui Module / TextAnimatorUGTK Completed
Text Animator UGTK
Summary
TextAnimatorUGTK animates TextMeshPro text per character from a single component. Write tags in the
text (<wave>, <shake>, <rainb>, {pop}, {#fade}…) or leave it plain; add an optional
typewriter that reveals the text with inline actions and events, and can make it disappear. Native
TMP rich-text tags (<b>, <color>, <sprite>…) keep working; unknown tags are stripped, never
printed. Everything is editable from the Inspector.
Scope. Working system: parser (3 phases + actions/events), 35+ built-in effects, modifiers, units (char/word/line/all), range+wiggly selectors, playback envelopes, 31 easings, stagger, typewriter with per-category timing, Backspace/ReplaceRange/SkipToNextMarker, wait-for-input, disappearance order, Time Source, accessibility. See the Roadmap for the honest spec-coverage list.
Supersedes. The old RainbowColorSystem module has been removed: use
<rainb>for rainbow text. For non-text targets (Images, whole objects) the object-level systems remain the way to go: JellySystem, FadeControllerSystem, CameraShake, GradientSystem. TextTyperSystem is kept for backward compatibility and can delegate here via itsuseTextAnimatortoggle.
Content
Modules Dependencies
- TextMeshPro (
com.unity.textmeshpro).
Setup
Add Mn_TextAnimatorUGTKText (UGTK/UI/Text Animator UGTK) to a GameObject with a TextMeshPro
text (TextMeshProUGUI or TextMeshPro). Type your text — with or without tags — in Source Text.
Ready-made prefabs in Prefabs/: the base TextAnimatorUGTK Text plus one demo prefab per
feature (TA_Wave, TA_Shake, TA_Stack, TA_UnitWord, TA_Stagger, TA_Selector,
TA_Playback, TA_EasingPop, TA_Jelly, TA_Neon, TA_Typewriter), each with a coherent
demonstration text baked in. All of them are placed in Debug/TextAnimatorScene.unity.
How To Use
Tag phases
- Persistent: <id ...> ... </id> (or </>). Animates continuously while visible.
- Appearance: {id ...} ... {/id} (or {/}). Plays as a character is revealed by the typewriter.
- Disappearance: {#id ...} ... {/#id} (or {/#}). Plays as a character is removed (StartDisappearing()).
- Stacking: <shake><wave>text</></>.
Modifiers — <wave a=20 s=8 f=0.4 unit=word stag=0.03 stagfrom=center ease=elasticout>
- a amplitude · s speed · f per-unit phase.
- unit = char (default) / word / line / all — the animated unit (§6 of the spec).
- stag seconds of stagger between units · stagfrom = start / end / center.
- ease = any of the 31 standard easings (quadin…bounceinout), applied to appearance progress and playback.
- Selectors (the competitor has none): selstart/selend (percent, or indices with the selidx flag),
selshape = square/rampup/rampdown/triangle/smooth, selamount 0..100; wiggly: wig 0..1,
wigs speed, wigcorr correlation.
- Playback: dl delay · fi fade-in · st still · fo fade-out · cyc cycles (0 = forever) ·
dbc delay between cycles · flags once, pingpong (+d half-period).
- Operators: = set, * multiply the default, + offset the default (a*2, s+1). Bare words are flags.
Built-in effects
- Persistent: wave bounce float drift wiggle shake swing/rot pend dangle wobble pulse/size/incr breathe heartbeat jelly squash stretch elastic arc orbit fade flicker neon rainb/rainbow
- Appearance: pop/popin size/incr slideh slidev drop/fall float/floatin rollin stretchin fade/fadein
- Disappearance: any of the above (fade / scale / slide out); characters without a {#} tag fade out by default.
Inline actions & events (fired by the typewriter when it reaches them)
- <waitfor=1.5> pause · <speed=2> change speed · <pause> / <resume> · <waitinput> waits for
SubmitInput() (or any key with the legacy Input Manager; fires onWaitingForInput) ·
<?eventName=arg> fires onMessage.
var t = GetComponent<Mn_TextAnimatorUGTKText>();
t.Text = "<wave>Level <bounce>up!</bounce></wave>"; // re-parses, restarts the typewriter
t.SetText("Plain", restartTypewriter: false);
t.AppendText(" more");
t.StartTyping(); t.SkipTypewriter();
t.SkipToNextMarker(); // partial skip (competitor gap #1)
t.Backspace(3); t.StepForward(2); t.StepBackward(1); // competitor gap #2
t.ReplaceRange(0, 5, "Ciao"); // competitor gap #3 (source-level)
t.SubmitInput(); // continue after <waitinput>
t.SetEffectIntensity("wave", 0.5f); // Weighted playback from gameplay
t.PlayEffectOnce("shake"); // one-shot trigger on a tag
t.ManualTick(0.016f); // Time Source = Manual
t.StartDisappearing(); // plays {#...} / default fade out (order configurable)
float p = t.TypewriterProgress; // 0..1
Accessibility: Intensity Multiplier (0..1) scales every effect (0 = animation off, text readable).
Time Source: Scaled / Unscaled (keeps running while paused) / Manual (ManualTick(dt) — animatable
from Timeline or custom clocks).
Events (Inspector UnityEvents): onCharacterVisible(int), onTypewriterCompleted,
onMessage(id, arg), onTextDisappeared, onWaitingForInput.
Testing Scene
Open TextAnimatorScene in the module's Debug/ folder.
What to do, in order:
- Play the scene and watch each of the sample effects run.
- Type a tag by hand into a label that has no animator attached.
- Mix two tags on the same span of text.
- Use a tag on a label whose font lacks some of the glyphs.
Step 2 is the one worth remembering: without the animator the tag is not interpreted, it is printed, so the player reads the markup. That is the usual explanation for stray braces appearing in a build.
TextAnimatorScene, with one line per effect: wave, shake and wiggle, stacked bounce plus
rainbow, word-unit wave, staggered pulse, the triangular selector, the breathing fade, jelly
and squash and heartbeat, and the neon trio. Each line's text lives in sourceText with its
tags, not in the TMP field.
Technical Info
- Mn_TextAnimatorUGTKText: the component — parses the source, drives the typewriter (with inline actions/events and disappearance) and rewrites the TMP vertex/colour buffers each frame (per-character offset, rotation, per-axis scale, colour, alpha). Original vertices are cached on text change; the hot loop is allocation- and reflection-free.
- TextAnimatorUGTKParser: source → clean string (TMP tags forwarded) + effect ranges + action/event
markers, all in clean-string index space.
<noparse>supported; only known ids are consumed. - TextAnimatorUGTKEffects: built-in persistent/appearance/disappearance effect evaluator (pure math).
- CharMod / S_TextAnimatorUGTKRange / S_TextAnimatorUGTKMarker / TextAnimatorUGTKArgs / E_TextAnimatorUGTKCategory: data types.
Roadmap
Spec coverage (vs the TextAnimator competitor spec):
- ✅ Done: one component · 3-phase parser (+ actions/events) · 35+ effects · modifiers (=,*,+, flags) ·
units char/word/line/all · range + wiggly selectors · playback (delay/fade-in/still/fade-out/
cycles/pingpong/once + Weighted via SetEffectIntensity + PlayEffectOnce) · 31 easings · stagger
(start/end/center) · typewriter with per-category timing (punctuation/space/newline) · inline actions
(waitfor,speed,pause,resume,waitinput) & events · Backspace / ReplaceRange / SkipToNextMarker /
Step (the competitor's documented gaps) · disappearance order (start/end/random/simultaneous) ·
Time Source (scaled/unscaled/manual) · accessibility intensity.
- ⬜ Next: ScriptableObject data model (EffectAsset/Database/Presets) · styles/macros · expression &
spatial/regex selectors · shader-based effects · visual tag editor + edit-mode preview · autocomplete/
linter · typewriter voice/audio & karaoke sync · localization tag-safe · migration tool · Burst backend ·
test suite.
© 2026 Marcello De Bonis. All rights reserved
Depends on 0
- Standalone: no other module required.
Used by 1
Measured from the repository: code references (asmdef) plus prefab and asset GUIDs. Importing this module alone brings in 0 modules in total.
UGTKengine within an engine


