v4.0 · Unity 2021.3+

TypeFlow Pro

Correct, animated Arabic / Hebrew / right-to-left text for TextMeshPro — plus a pure-C# OpenType engine for the scripts, fonts and effects TMP's atlas can't reach. No migration, no native binaries.

Unity 2021.3+ Pure C# · No native code TextMeshPro RTL / Arabic / Hebrew
Two tiers, one package. Tier 1 enhances the TextMeshPro you already use — add one component for correct shaping, BiDi and animation, with zero migration. Tier 2 ("Kiln") is a standalone pure-C# OpenType renderer for scripts, variable fonts, color emoji and effects TMP can't express.
Proven correctness. Measured against the official Unicode conformance suites and locked by regression-floored tests — not a single hand-waved aggregate. See Unicode Conformance.

This guide covers both tiers. Tier-1 (TextMeshPro) topics come first; the pure-C# Kiln engine follows; shared concepts and reference are at the end.

Installation

Import once, run the Setup wizard, add a component.

Import from the Asset Store
In Window → Package Manager → My Assets, download and import TypeFlow Pro. It lands at Assets/TypeFlowPro/.
Import TMP Essentials
Window → TextMeshPro → Import TMP Essential Resources (needed for the Tier-1 TextMeshPro path).
Run the Setup wizard
Tools → TypeFlow Pro → Setup — it verifies TMP and helps you build an Arabic-capable font atlas (it lists the presentation-form ranges to include).
Add a component
TypeFlow Text on a TMP object for the Tier-1 path, or Kiln Text for the standalone Tier-2 renderer.

Requirements

What gets installed

Assets/TypeFlowPro/

  Runtime/        // Unicode (BiDi, segmentation, layout), Fonts (shaping/render),

                  //   Core (pipeline + TypeFlowText), Kiln (Tier-2), TypeFlow (animation)

  Editor/         // Setup Wizard, Font Diagnostics, Conformance Runner, inspectors

  Demos/          // bundled Amiri font + a guided, interactive showcase scene

                  //   (every feature, page by page) you can open and play

  Documentation/  // You are here

  Tests/          // EditMode + PlayMode (run headless via Unity -runTests)Project
Zero lock-in. TypeFlow Text is an ITextPreprocessor — disable or remove the component and your text reverts to plain TextMeshPro. Nothing is rewritten on disk.

Quick Start: Arabic on TextMeshPro

Correct, joined, right-to-left Arabic on your existing TMP objects — in about ten seconds.

Add a TextMeshPro object
A TextMeshPro - Text (UI) or TextMeshPro (3D), as usual. Assign an Arabic-capable font asset.
Add the TypeFlow Text component
Add Component → TypeFlow Pro → TypeFlow Text.
Type Arabic into the TMP text field
That's it — letters join, the line orders right-to-left, and mixed numbers/English are placed correctly.
(Optional) Animate it
Add TypeFlow Animator and enable the typewriter — it reveals in logical reading order, correct even for RTL.
💡
Set the direction explicitly if you know it. BaseDirection.Auto uses the UAX #9 first-strong rule; set RightToLeft or LeftToRight for a fixed layout.

🔥 Quick Start: Kiln Engine (Tier 2)

Render any font with its own OpenType tables — no TextMeshPro, no native code.

Import a font as bytes
Drop a .ttf/.otf into your project and rename the extension to .bytes (so Unity imports it as a TextAsset).
Add a Kiln Text component
Add Component → TypeFlow Pro → Kiln Text (Tier 2) on an empty GameObject (it adds a MeshFilter + MeshRenderer).
Assign the font + type text
Drag the .bytes font into the Font slot and set the text. Kiln shapes it with the font's GSUB/GPOS, rasterizes glyphs to its SDF atlas, and draws with the KilnSDF shader.
(Optional) Wrap & align
Set Max Width (> 0 enables word wrap) and the alignment. See Kiln Text for all fields.
When to use Kiln vs. Tier 1. Use Tier 1 for normal Arabic/Hebrew/RTL UI on TextMeshPro. Reach for Kiln when you need scripts, variable-font axes, or color emoji that TMP's pre-baked atlas can't express.

How It Works (Tier 1)

A string becomes correct, animated RTL text in one preprocessing pass.

Source text Strip anim tags Arabic shaping BiDi (UAX #9) Mirror TMP renders Animator
  1. TfpTagParser strips TypeFlow Pro's own animation tags (keeping TextMeshPro markup).
  2. ArabicShaper applies logical-order contextual joining + lam-alef ligatures.
  3. Bidi.Resolve computes UAX #9 embedding levels and the visual order.
  4. Mirroring (rule L4) produces the visual string and a VisualToSource cluster map.
  5. TextMeshPro renders the visual string with its own atlas and shaders.
  6. TypeFlowAnimator reveals/animates the TMP mesh, using the cluster map so the typewriter follows logical reading order (correct for RTL).
It's a preprocessor. TypeFlow Text implements TMPro.ITextPreprocessor, so TMP calls it automatically before layout. There is no second mesh, no extra draw call, and no per-frame allocation in steady state.

📝 TypeFlow Text

TypeFlowPro.TypeFlowText — the Tier-1 component. Add it to any object with a TMP_Text.

MemberDescription
BaseDirection BaseDirectionParagraph direction: Auto (UAX #9 first-strong), LeftToRight, or RightToLeft. Setter re-processes.
bool EnableArabicShapingToggle contextual joining + lam-alef ligatures. Setter re-processes.
byte LastParagraphLevel0 = LTR, 1 = RTL of the last preprocess.
ProcessedText LastProcessedVisual string + cluster map of the last preprocess.
ParsedText LastParsedStripped animation data of the last preprocess.
event Action TextProcessedRaised after each preprocess.
string PreprocessText(string)ITextPreprocessor entry point (called by TMP).
void Refresh()Force TMP to re-run preprocessing.

Auto-flip alignment (so RTL text right-aligns automatically) is a serialized option on the component.

🎬 TypeFlow Animator

TypeFlowPro.TypeFlow.TypeFlowAnimator — the animation driver. Add it alongside TypeFlow Text.

Typewriter

Enable the typewriter to reveal text character-by-character. Because reveal follows the cluster map, Arabic appears right-to-left in the correct order, not backwards. Configure characters-per-second, play-on-enable, and a punctuation pause.

Control & events

MemberDescription
Play() / Pause() / Skip() / Restart() (alias Replay())Typewriter control.
SetTextAndPlay(string)Set the label's text (TFP tags allowed) and restart the reveal from the top.
Continue()Release a <waitinput> hold so the typewriter resumes (call on player input).
PlayOut()Play the disappearance (exit) animation.
SetTypewriterSound(AudioSource, AudioClip[], volume, pitchJitter, everyN)Wire a per-character click sound at runtime (random clip + pitch jitter; skip whitespace).
bool IsPlaying / IsComplete / IsWaitingForInputCurrent state.
float Progress / int VisibleCharactersReveal progress (0..1) and the count of revealed characters — for progress bars / gating.
event Action<int> CharacterRevealedFires with the logical index as each character appears.
event Action<int> WordRevealedFires with the word index as each whole word finishes revealing.
event Action WaitingForInputFires once when the typewriter parks at a <waitinput>; call Continue() to resume.
event Action<string> EventTriggeredFires when a <event=name> tag is reached.
event Action TypewriterCompletedFires when the reveal finishes.
event Action HiddenOutFires when a PlayOut() disappearance finishes.
var anim = GetComponent<TypeFlowAnimator>();

anim.WordRevealed   += w => { /* sync a voice clip per word */ };

anim.EventTriggered += name => { /* react to <event=name> */ };

anim.WaitingForInput += () => ShowContinuePrompt();   // parked at <waitinput>

anim.TypewriterCompleted += () => AdvanceDialogue();



anim.SetTextAndPlay("Hello <wave>world</wave>!<waitinput> Ready?");

if (Input.GetMouseButtonDown(0)) anim.Continue();      // release the wait

progressBar.fillAmount = anim.Progress;                // 0..1

anim.Skip();   // reveal everything nowC#

Common recipes

Dialogue box that waits for input. Use <waitinput> between sentences and call Continue() on a click; WaitingForInput tells you when to show a prompt.

anim.WaitingForInput += () => prompt.SetActive(true);

anim.SetTextAndPlay("Hello, traveler!<waitinput> The road is dangerous.<waitinput> Continue?");



void Update() {

    if (anim.IsWaitingForInput && Input.GetMouseButtonDown(0)) {

        prompt.SetActive(false);

        anim.Continue();

    }

}C#

Word-by-word voice / SFX sync. Reveal whole words and react per word.

anim.Reveal = TypeFlowAnimator.RevealUnit.Word;

anim.WordRevealed += wordIndex => PlayBlip(wordIndex);

anim.Restart();C#

Animate shaped Arabic. Behaviors work on the RTL-shaped glyphs — just tag the text; the typewriter still reveals in correct logical order.

arabicLabel.text = "<wave>مرحبا</wave> <rainbow>بالعالم</rainbow>";

// (TypeFlow Text handles shaping/BiDi; TypeFlow Animator animates the result)C#

Different entrance per word. Override the global entrance per span, optionally with its own timing.

label.text = "<appear=pop ease=back>Bounce</appear> <appear=scale dur=0.8>grow</appear> in!";Text

Auto-hide toast (show → hold → vanish). Reveal, then play the disappearance after a delay.

anim.Disappearance = EntranceStyle.FadeIn;   // reversed for exit

anim.TypewriterCompleted += () => StartCoroutine(HideAfter(2f));

anim.HiddenOut += () => gameObject.SetActive(false);

anim.SetTextAndPlay("Saved!");

// IEnumerator HideAfter(float s){ yield return new WaitForSeconds(s); anim.PlayOut(); }C#

Animation Tags

Inline tags drive per-character motion. They are parsed before TMP sees the text; any other <...> markup passes through to TextMeshPro.

Hello <wave>world</wave>! <shake a=6 f=20>Danger</shake>

مرحبا <wave>بالعالم</wave>Text

Behavior tags — 20 built-in

TagEffectChannel
<wave>Vertical sine wave (travelling per-character).Position
<bob>Vertical bob, all letters in unison.Position
<sway>Horizontal sway, in unison.Position
<slide>Horizontal travelling sway (per-character).Position
<float>Slow elliptical drift.Position
<bounce>Bounce (absolute-value sine).Position
<wobble>Circular sway.Position
<wiggle>Organic 2-D wander.Position
<shake>Energetic multi-sine shake.Position
<jitter>Per-step hashed noise.Position
<tremor>Subtle high-frequency rumble.Position
<swing>Rotate back & forth, in unison.Rotation
<dangle>Travelling wave of rotation.Rotation
<pendulum>Gentle phased swing.Rotation
<spin>Continuous rotation (a ≈ deg/sec).Rotation
<pulse>Scale in/out.Scale
<heartbeat>Sharp scale pulse (a living throb).Scale
<rainbow>Hue cycling.Colour
<fade>Alpha pulses up & down.Alpha
<blink>Alpha toggles on/off.Alpha

Close any behavior with its matching tag, e.g. <wave>…</wave>. Attributes: a = amplitude, f = frequency — e.g. <wave a=12 f=3>. Register your own tag in C# with TfpEffects.Register("name", …), or with no code via a Custom Effect ScriptableObject (Create ▸ TypeFlow Pro ▸ Custom Effect) on a TfpEffectRegistrar.

Stack effects by nesting. Tags combine when nested — positional offsets add, scales multiply, rotations add, and colour/alpha effects chain. For example <wave><rainbow>hello</rainbow></wave> both waves and cycles colour. A global default effect (set on the component) applies to any untagged glyph and is replaced — not stacked — where you add an explicit tag.

Appearance & disappearance tags

TagEffect
<appear=pop>…</appear>Give this span its own entrance (fade, pop, scale, slideup/down/left/right, rotate), overriding the global entrance.
<appear=pop dur=0.5 ease=back>Optionally give that span its own duration (dur/d, seconds) and easing (ease/e: linear, back, bounce, elastic, sine, expo, cubic, … with in/out variants). Omit either to inherit the component's global timing.
<disappear=down dur=0.8>…</disappear>Give this span its own exit (with optional dur/ease too), played by PlayOut().

Pacing & dialogue tags

TagEffect
<speed=0.5>…</speed>Change reveal speed for the span.
<pause=0.4>Hold the typewriter for N seconds.
<waitfor=0.4>Timed hold (same as pause).
<waitinput> / <waitfor>Halt the typewriter here until you call Continue() — perfect for dialogue boxes. Fires WaitingForInput.
<event=name>Fire TypeFlowAnimator.EventTriggered with name.
// A dialogue box that waits for the player between sentences

text.text = "Hello, traveler!<waitinput> The road ahead is dangerous.<waitinput> Continue?";

anim.WaitingForInput += () => { /* show a 'press to continue' prompt */ };

// on player input: anim.Continue();C#

🔄 RTL, Alignment & Digits

The details that make mixed-direction text look right.

Bidirectional layout

The full UAX #9 algorithm (including directional isolates) orders mixed Arabic/Hebrew/Latin/number runs correctly. Numbers and Latin words embedded in an RTL line stay left-to-right within the right-to-left flow.

Alignment auto-flip

With auto-flip enabled, a paragraph that resolves to RTL right-aligns automatically, matching reader expectation without you toggling alignment per string.

Digit shaping

Optional contextual digit shaping maps ASCII digits to Arabic-Indic or Eastern Arabic-Indic (Persian) forms based on context, so "2026" can render with native digits where appropriate. Kashida justification and Persian/Urdu presentation forms are also supported.

💡
Markdown. TypeFlow Pro can convert a small Markdown subset to TMP rich text, so **bold** and *italic* work in your dialogue strings.

🔥 Kiln Text (Tier 2)

TypeFlowPro.Kiln.KilnText — a world-space text renderer that shapes and draws a font entirely in C#.

Kiln parses a font's own tables (TrueType glyf and CFF/Type2), applies GSUB and GPOS, rasterizes glyphs to an SDF atlas, and draws them with a MeshRenderer + the KilnSDF shader — no TextMeshPro and no native code.

FieldDescription
Font AssetA .ttf/.otf imported as bytes (rename to .bytes). Or call SetFont(byte[]) at runtime.
TextThe string to render. Settable via the Text property.
Pixel Size / World ScaleRasterization size and world-unit scale.
ColorTint applied through the KilnSDF material.
Base DirectionAuto / LeftToRight / RightToLeft — mixed-BiDi glyphs are reordered with the UAX #9 L2 rule.
Script"auto" (default) detects the script from the text and routes complex scripts (Devanagari, Thai, …) through the full reordering/feature shaper; Arabic/Hebrew/Latin use the Arabic shaper. Force a specific OpenType tag ("arab", "deva", "thai", …) if you need to.
Max WidthWorld-unit line width. 0 = single line; > 0 enables word wrap (full UAX #14 line breaking).
Line Height Multiplier / AlignmentMulti-line spacing and Left/Center/Right/Justify alignment.

Complex scripts, color emoji & variable fonts

Feed Kiln the right font and it just works — the component detects the script and picks the shaper, composites COLR/CPAL color emoji as tinted SDF layers, and can interpolate a variable font's axes at runtime:

var kiln = GetComponent<KilnText>();



// Complex script: auto-detected, conjuncts/marks shaped from the font's GSUB/GPOS

kiln.SetFont(devanagariFont.bytes);

kiln.Text = "नमस्ते";          // the स्त conjunct forms (Script = "auto")



// Color emoji: load a COLR/CPAL v0 font and type emoji — rendered in full colour

kiln.SetFont(emojiFont.bytes);

kiln.Text = "🚀❤🎉";



// Variable font: drive a weight (or any) axis live

kiln.SetFont(interVariable.bytes);

if (kiln.HasVariableAxes) kiln.SetVariation("wght", 700f);  // re-interpolates & re-rasterizesC#
💡
Bring your own font. The engine ships no emoji/CJK/Indic fonts — point Kiln at any font you have the rights to and it renders from that font's own tables. Color emoji need a COLR/CPAL v0 font (e.g. OpenMoji, Twemoji Mozilla); bitmap emoji fonts (CBDT/sbix) are not used.

Inline effects

Kiln understands the same inline effect tags as the Tier-1 style parser, applied to the glyphs it shapes:

TagEffect
<gradient=RRGGBB,RRGGBB>…</gradient>Per-glyph vertical gradient (top colour, bottom colour) baked into the mesh vertex colours — works on shaped Arabic/complex text too.
<outline=RRGGBB,width>…</outline>Outline ring via the KilnSDF material (applied to the text run).
<shadow=RRGGBB,dx,dy>…</shadow>Drop shadow via the KilnSDF material (applied to the text run).

Tags are stripped before shaping, so they never render as literal text. Example: <gradient=FF4040,FFD23E>سلام</gradient> renders joined Arabic with a red→gold vertical gradient on each letter.

Pure C#, AOT-safe. The Kiln engine compiles for IL2CPP → WebAssembly with zero native dependencies (both WebGL and Windows-IL2CPP builds are verified clean).

🌐 Scripts & Fonts

What the engine shapes today, and the OpenType features behind it.

🇦 Arabic / Hebrew / Latin

Contextual joining, ligatures, mark positioning, full BiDi.

🇨 CJK

Han/Kana rendered from the font's own tables.

🕊 Devanagari

Reordering + conjunct formation (e.g. नमस्ते).

🇹 Thai

Consonants + above/below marks, with dictionary word-breaking.

OpenType features supported

Scope. Latin, Arabic, Hebrew, CJK, Devanagari (conjuncts) and Thai are render-validated. Myanmar/Khmer cluster shaping is on the roadmap (they fall back rather than reorder).

🎨 Families, Links & Effects

Rich-text building blocks that work across both tiers.

Font families

Create a Font Family asset (Assets → Create → TypeFlow Pro → Font Family) holding Regular / Bold / Italic / Bold-Italic faces plus optional fallbacks. <b>/<i> then pick the correct face, with CSS-style graceful degradation (faux-bold / faux-italic when a face is missing).

// Whole-text: set the right face + faux style for a bold/italic state

family.ApplyTo(myTmpText, bold: true, italic: false);



// Mixed text: rewrite <b>/<i> into per-run <font> spans

string markup = family.ToTmpMarkup("plain <b>bold</b> text");C#

Clickable links

The easiest path is the TypeFlow Clickable Text component (Add Component → TypeFlow Pro → TypeFlow Clickable Text) on any TextMeshPro label: set its Source to text with <link=id>…</link> markup and wire OnLinkClicked in the inspector. It strips the link tags (other markup like <color> passes through), pushes the clean text to the label, and hit-tests clicks and hover for you.

var clickable = label.gameObject.AddComponent<TfpClickableText>();

clickable.Source = "Visit the <link=home>home page</link>.";

clickable.OnLinkClicked.AddListener(id => { /* the user clicked link 'id' */ });

clickable.LinkHovered += id => { /* hovered link id, or null */ };C#

Under the hood it uses the pure-geometry primitives, which you can also call directly (e.g. for a Kiln layout):

string clean = LinkParser.Parse(source, out var links);

// boxes from TextMeshPro (or your Kiln layout):

var boxes = LinkHitTester.BoxesFromTextMeshPro(tmpText);

string id = LinkHitTester.GetLinkIdAt(localPoint, boxes, links);

if (id != null) { /* the user clicked link 'id' */ }C#

Inline effect tags

StyleTagParser parses these into style spans applied by the Kiln SDF renderer. Gradients apply via per-glyph vertex colours; the rest are computed in the KilnSDF shader (crisp at any size, resolution-independent, ~free, WebGL-safe). All tags nest and stack, and work on any script including Arabic/RTL.

TagEffect
<gradient=RRGGBB,RRGGBB>Per-glyph vertical colour gradient (top, bottom).
<outline=RRGGBB,width>SDF outline ring.
<shadow=RRGGBB,dx,dy>Soft drop shadow (UV offset).
<glow=RRGGBB,intensity,radius>Soft outer halo / neon glow from the distance falloff.
<longshadow=RRGGBB,dirX,dirY,length>Solid directional long-shadow streak (flat/retro).
<bevel=intensity,width,angle>Faux-3D emboss lit from the SDF gradient (raised/engraved look).

Example: <outline=101018,0.1><bevel=1.6,0.2,120>STEEL</bevel></outline> or <glow=39E6FF,2.2,0.4>NEON</glow>. See the SDF Effects page in the showcase.

Roadmap. Per-span effect mesh rendering (mixing several gradient/outline/shadow spans within one string in the Tier-2 renderer) is being finished; the parsers and whole-object application ship today.

💥 Damage Numbers

Pooled, animated floating combat text — built on the same per-character engine as the rest of TypeFlow Pro, so it does things a generic popup system can't: per-digit entrances, live behaviors, and RTL Arabic-Indic / Persian numbers.

Spawn a number with one call. The first call lazily creates a persistent world-space manager; for full control, drop a TfpDamageNumberManager in your scene or assign your own to TfpDamageNumbers.Default.

using TypeFlowPro.CombatText;



// One-liner — a pooled popup floats up at a world point and fades out:

TfpDamageNumbers.Spawn(150, hitPoint);



// With a no-code style asset (Assets ▸ Create ▸ TypeFlow Pro ▸ Combat Text Style):

TfpDamageNumbers.Spawn(critDamage, hitPoint, critStyle);



// Your own manager — world or canvas, follow a moving enemy, combine rapid hits:

manager.Spawn(heal, enemy.position, healStyle, follow: enemy.transform);C#

The popup style asset

A TfpPopupStyle is a ScriptableObject that defines the whole look — no code. Hand it to Spawn. (Leave it out and the manager uses a sensible default.)

Field groupWhat it controls
Font, FontSize, FontStyle, ColorRendering. ColorByValue + a ValueGradient make bigger hits glow hotter.
Abbreviation, Decimals, ThousandsSeparatorNumber formatting: metric abbreviation (1234567 → 1.2M), grouping, fixed decimals, plus a Prefix/Suffix.
DigitsWestern, ArabicIndic (٠-٩) or Persian (۰-۹) — combat text in the player's own numerals.
Lifetime, Rise, RiseDistance, ArcHeight, DirectionHow it travels: straight Up, a Directional drift, or a parabolic Arc (loot/XP toss).
StartScale, ScaleEase, PopInFraction, EndScaleThe pop-in (use an OutBack ease for overshoot) and an optional shrink as it dies.
FadeInFraction, FadeOutFractionThe transparency in/out windows.
ShakeAmplitude, ShakeFrequency, SpinDegreesThe classic crit shake and optional spin.
PerCharacter, EntranceStyle, ContinuousEffectAnimate each digit independently with the TypeFlow engine — a staggered entrance plus a continuous behavior (Wave, Rainbow…).
Combine, CombineRadius, CombineWindowMerge rapid hits in the same spot into one rising total (DPS-meter feel) instead of overlapping popups.
FaceCameraBillboard world-space popups toward the camera.

Components & API

MemberDescription
TfpDamageNumbers.Spawn(value, worldPos, style?, follow?)Static one-liner; routes to Default (auto-created, persistent, world-space).
TfpDamageNumberManagerPools and spawns popups. WorldSpace toggles 3D TextMeshPro (billboarded) vs canvas TextMeshProUGUI under a Container. Prewarm avoids first-hit hitches.
TfpDamageNumberOne pooled popup. Drives a TMP_Text through its life; exposes Value, DisplayText, IsAlive.
TfpPopupStyleThe no-code style asset (above). BuildFormat() / BuildMotion() compile its fields into the pure structs the runtime uses.
TfpNumberFormat.Format(value, fmt)Pure, culture-invariant value→string (abbreviation, grouping, decimals, prefix/suffix, digit substitution). Reusable on its own.
World and canvas, one API. Games usually want world-space text floating over enemies (3D TextMeshPro, billboarded). Set WorldSpace = false and a Container under a Canvas for HUD/screen-space popups instead — the same Spawn call drives both. It's all C#, AOT-safe, and pools every instance so steady combat allocates nothing.
💡
See it live. The bundled showcase scene's Damage Numbers page fires 24 ready-made presets in a scrollable panel — hit, crit (shake + per-digit pop), heal, a combining DPS burst, loot arc, metric-abbreviated big hit with colour-by-value, Arabic-Indic & Persian numerals, per-character rainbow, poison/burn/freeze/lightning status ticks, mana & shield, 360° spin, heartbeat pulse, directional knockback & pierce, thousands-grouped, gold, combo multiplier, overkill, and a slow-mo shrink — each just a TfpPopupStyle built in a few lines.

3D & more

Further v4 capabilities — most have a live page in the bundled showcase to try.

FeatureWhat it does & how
3D extruded textKilnText3DTRUE 3D geometry extruded from ANY OpenType font in pure C# (face + sides + depth/bevel, separate submeshes/materials). Runs the same shaper, so Arabic joins in 3D and complex scripts shape; Built-in/URP/HDRP + WebGL. k3d.SetFont(bytes); k3d.Text = "نص"; k3d.Depth = 0.2f;
Text decal APITfpTextDecalExperimental mesh-projection component for shaped text on 3D surfaces. The runtime code and tests are present, but this is not currently a main showcase page; verify it on your target surfaces and pipeline before using it in marketing screenshots.
Curved / path textBend the baseline along an AnimationCurve: anim.ShapeCurve + ShapeAmplitude (+ ShapeScrollSpeed to travel), or wrap into a ring with ShapeRadial + ShapeRadius. Composes with behaviors/typewriter; Arabic/RTL too.
SDF text effectsNew inline tags <glow>, <longshadow>, <bevel> (see Inline effect tags) — crisp, per-glyph, resolution-independent, in the Kiln SDF shader.
RTL one-call converterTypeFlowRtl.ConvertOne call shapes + bidi-reorders logical text to a TMP-ready visual string — a drop-in migration path from "RTL fixer" plugins. No component needed.
Reduce-motion (a11y)Global switch TypeFlowAnimator.ReduceMotion = true instantly settles all animated text (events still fire) for motion-sensitive players.
Pixel-perfectKilnText.PixelPerfectSnaps each glyph quad to the pixel grid for crisp small text / pixel-art (no sub-pixel shimmer).

🏗 Two-Tier Architecture

One package, two ways to put correct text on screen.

 Tier 1 — TextMeshProTier 2 — Kiln
RendererTextMeshPro (its atlas + shaders)Pure-C# OpenType engine + KilnSDF shader
MigrationNone — add a componentNew component (Kiln Text)
Best forArabic/Hebrew/RTL UI & animationScripts/fonts/effects TMP can't express
Native codeNoneNone
Animation engineYes (typewriter + behaviors)Shares the same building blocks

The two tiers share the same Unicode foundation (BiDi, segmentation, shaping) — a clip of Arabic text shapes identically whether TMP or Kiln renders it.

📋 Included vs Scope

A buyer-facing map of what ships in this package, what needs your own project assets, and what TypeFlow Pro does not try to be.

AreaStatusDetails
TextMeshPro Arabic / Hebrew / RTLIncludedTypeFlow Text plugs into existing TMP UI and 3D objects for Arabic shaping, UAX #9 BiDi, mixed Latin/numbers, digit shaping and alignment auto-flip.
RTL-aware text animationIncludedTypewriter reveal, word reveal, 20 built-in behavior tags, appear/disappear tags, dialogue waits, callbacks, per-character sound and reduce-motion support.
Kiln pure-C# OpenType rendererIncludedStandalone MeshRenderer path for advanced font rendering: TrueType/CFF outlines, GSUB/GPOS shaping, variable fonts, COLR/CPAL color emoji, SDF/MSDF, outlines, shadows, gradients and pixel snapping.
Game text extrasIncludedClickable links, font families, Markdown conversion, font fallback APIs, damage numbers, 3D extruded text, auto-size, wrapping and ellipsis helpers. A text-decal API is present but should be project-verified before being treated as a headline feature.
Editor toolsIncludedSetup Wizard, Font Diagnostics and Conformance Runner under Tools → TypeFlow Pro.
FontsDemo font includedAmiri is bundled for the Arabic demo under the SIL OFL. For production language coverage, use fonts you have the rights to ship, especially for CJK, emoji and project-specific brand typography.
Render pipelinesSupportedBuilt-in Render Pipeline, URP and HDRP are supported for the main text/UI/Kiln paths.
Online services / AINot includedTypeFlow Pro is not an AI generator, translation service, localization database, account system or cloud tool. It has no API keys, no subscription and no runtime internet requirement.
Native pluginsNot usedNo HarfBuzz, FreeType or platform-specific binary plugin is bundled. The package is pure C# plus Unity shaders/components.
Every rare script/font edge caseActive scope areaArabic, Hebrew, CJK, Devanagari and Thai have validated paths. Myanmar/Khmer and some advanced per-font shaping edge cases remain areas to verify with project fonts.
Practical rule. Use TypeFlow Text first for normal localized UI and dialogue. Use Kiln when you need font features, scripts, color glyphs or rendering effects that a pre-baked TMP atlas cannot express.

Unicode Conformance

Measured against the official Unicode test suites and enforced by regression-floored tests.

Official suiteResultWhat it proves
GraphemeBreakTest100%User-perceived character boundaries (emoji ZWJ, etc.).
WordBreakTest100%Word boundaries (incl. flag pairs, Hebrew quotes).
SentenceBreakTest100%Sentence boundaries.
BidiCharacterTest99.97%The bidirectional algorithm over 91,707 official cases.
LineBreakTest99.73%UAX #14 line-break opportunities.

Reproduce them yourself: run the UnicodeConformanceTests and BidiCharacterConformanceTests headlessly. Each test prints its pass rate and asserts a regression floor, so conformance can't silently slip.

🔧 Editor Tools

Under Tools → TypeFlow Pro.

🔧 Setup

Verifies TextMeshPro and helps build an Arabic-capable atlas, listing the required Unicode ranges.

🔎 Font Diagnostics

Scans a TMP font asset and reports missing Arabic base/presentation glyphs.

✅ Conformance Runner

Runs the bundled UAX #9 BiDi vectors and shows pass counts.

📙 Scripting API

The stable public surface. Namespaces: TypeFlowPro, TypeFlowPro.Unicode.BiDi, TypeFlowPro.Fonts.Shaping, TypeFlowPro.TypeFlow.

Common usage

using TypeFlowPro;

using TypeFlowPro.Unicode.BiDi;



var tfp = GetComponent<TypeFlowText>();

tfp.BaseDirection = BaseDirection.Auto;

tfp.EnableArabicShaping = true;

tfp.Refresh();C#

Pipeline & BiDi (engine-level)

// One-shot processing without a component:

ProcessedText p = TypeFlowProcessor.Process(logical, ShapeSettings.Default);

// p.Visual, p.ParagraphLevel, p.VisualToSource, p.IsRightToLeft



// Raw bidirectional resolution:

BidiResult b = Bidi.Resolve(text, BaseDirection.Auto);

// b.ParagraphLevel, b.Levels, b.VisualToLogicalC#

Key types

TypePurpose
TypeFlowProcessor.Process(string, ShapeSettings)Logical → visual string + cluster map.
Bidi.Resolve(string|int[], BaseDirection)UAX #9 levels + visual order.
ArabicShaper.Shape(int[])Contextual joining → glyphs + source map.
TfpTagParser.Parse(string)Clean text + animation spans/events/controls.
KilnText.SetFont / Text / Script / SetVariation(tag,value)Tier-2 renderer: load a font, set text, force/auto a script, drive a variable-font axis (HasVariableAxes / VariationAxes).
TypeFlowProcessor.ProcessBatch(string[], ShapeSettings)Shape many strings in parallel (multi-core, thread-safe, cache-free).
KashidaJustifier.InsertKashidas(int[] cps, int count)Distribute Arabic tatweel elongations at the best joints for kashida justification.
FontFallback.SegmentRuns(int[] cps)Resolve a mixed-script string into per-font runs across an ordered font chain.
RevealScheduler / TextBehaviors / AnimationMapAnimation building blocks.
FontFamily / FontFamilyResolverFace selection + faux synthesis.
TfpClickableTextDrop-in clickable/interactive text component (click + hover on <link> regions).
LinkParser / LinkHitTesterClickable-text parsing + hit-testing primitives (used by the component).

💡 Troubleshooting

The issues that come up most, and how to fix them.

Arabic shows as disconnected / boxed letters

The font atlas is missing Arabic presentation forms. Run Tools → TypeFlow Pro → Setup and rebuild the atlas with the presentation-form ranges it lists, using an Arabic-capable font (Noto Naskh Arabic, Amiri, Cairo, Dubai). Use Font Diagnostics to confirm the glyphs are present.

Arabic appears backwards

Make sure the TypeFlow Text component is actually on the object (the TMP field alone won't reorder). If direction detection is wrong for your data, set BaseDirection to RightToLeft explicitly instead of Auto.

Mixed numbers/English sit in the wrong place

That ordering is governed by the bidirectional algorithm and is usually correct per UAX #9. If a specific string looks wrong, check whether you intended a fixed paragraph direction — setting BaseDirection explicitly removes the first-strong ambiguity.

The typewriter reveals RTL text in the wrong order

Use TypeFlow Animator (not a generic typewriter asset). It reveals via the cluster map in logical reading order, which is correct for RTL. Generic per-glyph typewriters reveal in visual order and look backwards on Arabic.

Kiln Text renders nothing

Confirm the font is imported as bytes (extension renamed to .bytes so it's a TextAsset) and assigned to the Font slot, and that the GameObject has the MeshFilter + MeshRenderer the component requires. Check the Console for font-parse messages.

A complex script doesn't shape correctly in Kiln

Latin, Arabic, Hebrew, CJK, Devanagari and Thai are validated; Myanmar/Khmer cluster reordering is not yet modeled. Also confirm the font actually contains the GSUB/GPOS features for that script — Kiln shapes from the font's own tables.

FAQ

Quick answers to the questions that come up most.

Do I have to migrate off TextMeshPro?

No. TypeFlow Text is an ITextPreprocessor — add it to your existing TMP objects and they start rendering correct Arabic/RTL. Remove it and you're back to vanilla TextMeshPro, with nothing rewritten.

Does it use native plugins?

No. Everything is pure C#. It runs on every Unity target including WebGL and consoles, with no per-platform native libraries (both WebGL and Windows-IL2CPP builds are verified clean).

Is TypeFlow Pro an AI or cloud service?

No. TypeFlow Pro is a local Unity text-rendering and animation toolkit. It does not generate translations, call an online AI model, require API keys, use credits, or need a runtime internet connection.

Which languages are supported?

Tier 1 (TextMeshPro): Arabic, Persian/Farsi, Urdu and other Arabic-script languages, plus Hebrew, with full BiDi for mixing them with Latin, numbers and punctuation. The Tier-2 Kiln engine additionally render-validates CJK, Devanagari (conjuncts) and Thai. Myanmar/Khmer cluster shaping is on the roadmap.

Does the typewriter work in Arabic?

Yes — it reveals in logical reading order using the cluster map, so Arabic appears right-to-left in the correct order, not backwards. This is a common bug in animation assets; TypeFlow Pro handles it.

Do rich-text tags (<color>, <b>) still work?

Yes. TextMeshPro tags pass through untouched; only TypeFlow Pro's own animation tags are consumed. (Deep interaction of arbitrary TMP markup inside reordered RTL runs continues to be hardened.)

What about performance?

Shaping is cached and only re-runs when the text changes; animation manipulates the existing TMP mesh with no per-frame allocations in steady state. No extra draw calls or materials. A multi-core batch API is included for processing many strings at once.

Does it work at runtime / in builds?

Yes. Both tiers run at runtime on any Unity build target. There is no editor-only dependency for rendering.

📬 Support

Need help? We're here for you.

📧

Get in Touch

Bug reports, feature requests, font/shaping questions — reach out and we'll get back to you.

✉ szekipapa77@gmail.com

We typically respond within 24–48 hours.

💬 Before contacting
  • Check the Troubleshooting section
  • Run Font Diagnostics for missing-glyph issues
  • Confirm the TypeFlow Text component is on the object
  • Check the Console for parse/shaping messages
📋 Helpful info to include
  • Unity version (e.g. 6000.0.30f1)
  • TypeFlow Pro version (v4.0)
  • Render pipeline (Built-in / URP / HDRP)
  • The font you're using + a sample string
Enjoying TypeFlow Pro? A review on the Unity Asset Store helps other developers discover the asset and helps us keep improving it. Thank you!

📜 Licenses & Notices

Everything legal in one place. The same notices ship as plain text in Third-Party Notices.txt at the package root, with the font licence also at Demos/Fonts/Amiri/OFL.txt.

💼 TypeFlow Pro

TypeFlow Pro © 2026. All rights reserved. When obtained through the Unity Asset Store, your use of this package is governed by the Unity Asset Store End User License Agreement.

🌐 Unicode data

The character-property tables used by the bidirectional algorithm and the Arabic shaper are derived from the Unicode Character Database. Use of Unicode data files is governed by the Unicode Terms of Use. Copyright © Unicode, Inc. Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. The tables are generated at author time; the raw UCD files are not redistributed here.

🖌 Bundled font — Amiri

Amiri-Regular.ttf, its AmiriKiln.bytes copy and the generated Arabic SDF TextMeshPro asset are licensed under the SIL Open Font License 1.1. Amiri is the only third-party font shipped inside this package. You must supply your own licensed fonts for production use; the engine renders from any font you provide at runtime.

Copyright 2010-2022 The Amiri Project Authors (https://github.com/aliftype/amiri).



This Font Software is licensed under the SIL Open Font License, Version 1.1.

This license is copied below, and is also available with a FAQ at:

https://openfontlicense.org/





-----------------------------------------------------------

SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007

-----------------------------------------------------------



PREAMBLE

The goals of the Open Font License (OFL) are to stimulate worldwide

development of collaborative font projects, to support the font creation

efforts of academic and linguistic communities, and to provide a free and

open framework in which fonts may be shared and improved in partnership

with others.



The OFL allows the licensed fonts to be used, studied, modified and

redistributed freely as long as they are not sold by themselves. The

fonts, including any derivative works, can be bundled, embedded, 

redistributed and/or sold with any software provided that any reserved

names are not used by derivative works. The fonts and derivatives,

however, cannot be released under any other type of license. The

requirement for fonts to remain under this license does not apply

to any document created using the fonts or their derivatives.



DEFINITIONS

"Font Software" refers to the set of files released by the Copyright

Holder(s) under this license and clearly marked as such. This may

include source files, build scripts and documentation.



"Reserved Font Name" refers to any names specified as such after the

copyright statement(s).



"Original Version" refers to the collection of Font Software components as

distributed by the Copyright Holder(s).



"Modified Version" refers to any derivative made by adding to, deleting,

or substituting -- in part or in whole -- any of the components of the

Original Version, by changing formats or by porting the Font Software to a

new environment.



"Author" refers to any designer, engineer, programmer, technical

writer or other person who contributed to the Font Software.



PERMISSION & CONDITIONS

Permission is hereby granted, free of charge, to any person obtaining

a copy of the Font Software, to use, study, copy, merge, embed, modify,

redistribute, and sell modified and unmodified copies of the Font

Software, subject to the following conditions:



1) Neither the Font Software nor any of its individual components,

in Original or Modified Versions, may be sold by itself.



2) Original or Modified Versions of the Font Software may be bundled,

redistributed and/or sold with any software, provided that each copy

contains the above copyright notice and this license. These can be

included either as stand-alone text files, human-readable headers or

in the appropriate machine-readable metadata fields within text or

binary files as long as those fields can be easily viewed by the user.



3) No Modified Version of the Font Software may use the Reserved Font

Name(s) unless explicit written permission is granted by the corresponding

Copyright Holder. This restriction only applies to the primary font name as

presented to the users.



4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font

Software shall not be used to promote, endorse or advertise any

Modified Version, except to acknowledge the contribution(s) of the

Copyright Holder(s) and the Author(s) or with their explicit written

permission.



5) The Font Software, modified or unmodified, in part or in whole,

must be distributed entirely under this license, and must not be

distributed under any other license. The requirement for fonts to

remain under this license does not apply to any document created

using the Font Software.



TERMINATION

This license becomes null and void if any of the above conditions are

not met.



DISCLAIMER

THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,

EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF

MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT

OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE

COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,

INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL

DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM

OTHER DEALINGS IN THE FONT SOFTWARE.
🔧 Not included

HarfBuzz is not included, linked or shipped — it is used in development only as an offline source of golden shaping outputs to cross-check this package's independent pure-C# implementation. The showcase's colour-emoji, world-script and variable-font pages use extra fonts (OpenMoji, Noto, Inter) that are deliberately kept outside the published package; those pages show an "assign a font" note without them.

TypeFlow Pro v4.0 · Built for Unity 2021.3+ · Pure C#, no native binaries

Support: szekipapa77@gmail.com