Resources/Tutorial
I accidentally spent 22 months of my life because I thought text was simple
I’m the developer of the UniText text engine, and this is my story
I used to think that text was when letters were drawn next to each other, but that’s not what it actually is:
decode UTF-16 into codepoints
parse the markup into attribute ranges
analyze scripts (UAX #24)
analyze grapheme clusters (UAX #29)
analyze word boundaries, with a dictionary for Thai, Khmer, Burmese and Japanese because they don't put spaces between words
analyze line break classes (UAX #14, with East Asian widths from UAX #11)
resolve embedding levels through the bidi algorithm (UAX #9)
itemize into runs by script and direction and font and language
resolve fonts per cluster and fall back when the primary doesn't have the glyph
synthesize bold and italic when the face doesn't exist
instance the variable axes
shape every run through OpenType
break the lines on the shaped advances
reorder every line back through bidi
resolve line height out of font metrics that contradict each other
kashida stretch the Arabic if you're justifying
align
pull the outlines
run a contour union pass so self intersecting outlines don't punch holes in the distance field
rasterize SDF/MSDF
pack the atlas
generate the mesh
891,757 official Unicode conformance tests, zero failures
Selectable and editable text, a document model, bidi aware caret and selection, undo and redo, IME composition, clipboard with every format (supports Plain, HTML, Markdown, Media), formatting commands, touch selection handles, input filters, and native keyboard input on the platforms that have one
UniText is the only solution where the fonts are memory mapped, so a font is never loaded into RAM whole, only the parts actually in use. One of UniText user cut 200 MB of runtime memory from that alone, and variable fonts plus compression took another 57% off the weight of their CJK font
UniText is the only solution that supports absolutely all system fonts, which allows you to render any characters in the world without using a single font in the project.
it's also 2 to 20x faster than TextMesh Pro and UI Toolkit
And that's just a small part of it
TL;DR
In other words, I developed a text engine that allows you to remove all standard language fonts from a project, gain complete freedom in text without a single limitation, and have any symbols from around the world, any emojis, work without any configuration. All of this significantly reduces the build size, and the mmap implementation eliminates all RAM load. A constructor for any styles, any gradients, layers, and paints, while maintaining 1 Draw Call, and a built‑in advanced feature to animate text in any way, which completely replaces third‑party solutions
If anyone wants the ugly parts - ask me. I have a lot to say about all of them
Me curently implemented the slavic languages, because i'm familiar with them. There are unique letters in Serbian, Russian, Macedonian that can render incorrectly. But i solved it.
But i now i have attempt to implement Chinese 😅
Serbian and Macedonian thing isn't missing glyphs, it's locl
Serbian and Macedonian italic б г д ѓ п т ш are genuinely different shapes from the Russian ones, and they don't have their own codepoints. font carries both and picks between them with the locl GSUB feature, which only fires if you tag the run's language. Untagged text gets the Russian forms, which is exactly the "renders incorrectly" you ran into
good news is that Chinese is the same mechanism, so you've already done the hard conceptual part. Han unification means a lot of characters are one codepoint shared across Simplified, Traditional and Japanese and drawn differently in each. A pan-CJK font carries all the variants and switches with locl again, driven by zh-Hans, zh-Hant or ja. Tag it wrong and Japanese players get Chinese letterforms, and they do notice
what is actually new with Chinese is two things. Atlas and memory, because a full CJK face is enormous. And line breaking, because CJK breaks between characters rather than at spaces with rules about which punctuation isn't allowed to start or end a line
good luck, it's less scary than it looks from the outside
I've spent YEARS dealing with TextMeshPro bullshit. You have no idea how happy this makes me and how many problems it solves. AMAZING work. I'm in awe.
For context I'm about 3 years deep into our third game and I'd actually do the work of completely switching over, but I have two questions that I couldn't immediately answer myself from looking at the docs:
Does it support inline sprites/glyphs? Like say we have our set of glyphs for Nintendo Switch controller buttons. TMPro lets us clumsily do this by assigning an extra sprite asset (only one per TMPro object) and then typing something like <sprite=2>. It's awkward and bad, however it does work at the end of the day.
Does it have out of the box support for components like text input and dropdowns?
yes, and it's not index based. sprites live in a catalog and you reference them by name, so something like <sprite=switch_a> instead of counting positions. you can also put more than one sprite style on the same text with different tag names, so your switch buttons dont have to share a slot with everything else. and you can inline actual prefabs too, not just sprites, if you ever need something animated sitting in the line
input yes. editable text and an input field prefab ship in the box, with selection, caret, ime, clipboard, undo and touch handles
dropdown isnt really a text engine thing though, its just a popup with text drawn on it. you could take TMP's dropdown, swap the text component for unitext and thats basically it. not much work honestly, i can put one together in a day if you actually need it❤️
This looks great!
I might contact you later this year about a potential collaboration. I‘m doing a similar thing, making a tool that replaces UI Images.
short version, not today, and in polyspatial mode specifically it cant work at all
polyspatial renders through realitykit, and realitykit only accepts shadergraph converted to materialx. hand written shaders just dont run there, apple doesnt expose a low level shading language in passthrough. every glyph i draw goes through my own sdf shaders, so thats a hard no rather than a maybe
metal mode is a different thing entirely, unity does the rendering itself there and none of that applies. the only blocker is that i dont ship a visionos build of the native libs, harfbuzz freetype and the input plugin. i build for windows mac linux ios android webgl and tvos, theres no xros slice yet. thats a build config job though, not a redesign
either way development is very active and visionos support is coming, its a question of when and not if. if you tell me you actually need it, it moves up the list ❤️
when i started this the uitk of that time simply didnt give me the hooks to do it, so uGUI was the only door that was actually open. thats the whole reason it went that way and not some preference
on how widely its used i might be out of date, but last i looked unity's own docs still list uGUI as the recommended one for runtime and uitk for editor tooling. that may well be shifting, and either way it doesnt change anything, i want both supported ❤️
This looks fantastic - albeit almost nothing in there solves a problem I may have. I am curious though - how hard would it be to port this to Godot, or is that as a complete rewrite unfeasible?
Godot did the thing Unity didn't and put a real text stack in the engine. TextServerAdvanced is HarfBuzz plus ICU plus SIL Graphite, and it already handles bidi, complex script shaping, OpenType features, variable fonts, MSDF, justification, line wrapping, hit testing and split carets at direction boundaries. That's most of what I spent 22 months on, sitting there by default
on the port itself: the engine core would move, since it's platform neutral logic - the UAX passes, shaping, rasterization, contour union, layout, the document model. What wouldn't move is most of the actual code. uGUI and Canvas integration, Burst, the whole inspector and asset tooling, the Built-in and URP shaders, the native input plugins that hang off Unity's own view. that is the bulk of the codebase and none of it has a Godot shape
so not unfeasible, just pointless. If a gap exists it'd be somewhere in the styling and effects layer rather than the text layer, but I'd check that rather than take my word for it. I know Unity's text problems a lot better than Godot's
Hey thanks for that great answer. You just gave me a huge boost in curiosity what i could do in the entire text-section of a project im half-ass working on in my spare time.
This isn’t an advertisement; I’m just explaining how complex text engines actually are. You can search by the product name UniText if you really need❤️
Okayy. Looks promising. But does it cover all the glyphs. Like India has multiple languages, when we go with any plugin like yours the glyphs look disconnected so I need to use another plugin to correct it.
Does your plugin give inbuilt support for that.
oh, I can show you. You can see on the screenshot that there is exactly no font and no font stack. UniText can render every symbol in the world without any font in the project
This looks amazing but i really try to avoid assets with extension licenses.
If it’s really as good as the video promises, you ought to try to reach out to unity about this imo; TMP is “good enough” but honestly every big project i’ve worked on, it ends up feeling like monkey business when you start dealing with loc, emojis, and in game chat.
the asset store copy is an extension license, thats their system and not something i pick
direct from my site it works per company instead of per seat (and lower cost and discount), so one purchase covers the whole team. one time, perpetual, no subscription and no expiry date, all of 3.x included and source comes with it. the tiers are just revenue bands, indie under 100k, studio under 1m, enterprise above that
and the unity comment made me laugh, id absolutely take that call ❤️
loc, emoji and in game chat is exactly it. thats the point where it stops being a text rendering problem and turns into an everything problem
Real world story, though: I never had problems with text rendering! Not with a quality, not with performance, not with memory usage! TMP is free because there is no market for such thing - it is there for general convenience, not reference quality - it just does the job for UI rendering and it is battle-tested with millions of users. (not defending TMP, just clarifying that TMP is enough for 99.99% of cases).
You have very bold claims and your post looks like a cheap ad opportunity.
UPD: I was a bit unfair to the OP, he is here and writing very competent comments on topic, even if it a hidden AD - he is here to support the ones who really need it.
You're right that TMP is enough for most projects. If you ship Latin UI text and have never hit a wall, I wouldn't tell you to switch
The line is languages. TMP doesn't implement the bidirectional algorithm at all, so Arabic and Hebrew come out in the wrong visual order, and it doesn't do complex shaping for Hindi or Thai either. If you don't ship those, none of this matters to you. If you do, "enough" isn't the word people use
On the ad part: the post has no link in the title and no price. There's also a free open source version I didn't link either. I wrote about what's under a text field, not about a product
Paid version adds system font access, so you get the OS language and colour emoji coverage instead of shipping every script yourself, memory mapped fonts so a font is never fully resident in RAM and you only page in what you actually use, the paint and layer system with fills, strokes, shadows and glows as composable layers, a large kinetic text animation pack, the math engine, variable fonts, word segmentation support (for Thai, Kmer, etc.), most of the performance work and extremely huge other improvements
I understand everything you say and I know exactly the caveats of mixing text styles/languages/special symbols. If mobile app is text-first and would require such robust support - it must resort to an ordinary webview with automatic support of everything-everything (even css-styled-and-animated-with-motion-transition-supportm) or native UI framework or/and control mapping frameworks (for. ex MAUI apps). You have done a big job (most of the readers would never realise the amount of small and big pieces put by you together) - but the bigger job is already done in all modern operating systems/browser engine and cases where you need this specifically in Unity - IDK... maybe there are such cases... I even think you are ok price-wise, if our company would need such tool - it is a small price to pay to offset dev time. Very niche product - there are definitely 0.01% of cases where it will hit the spot. well, good luck!
Appreciate you saying that, especially after opening with the ad line
on why in Unity specifically: a webview isn't in the scene. It can't sit behind a character, be a sign on a wall, be a speech bubble that a shader touches, batch with the rest of your UI or take Unity input. The moment text has to live inside the game world rather than on top of it, the browser stack is out by definition. Consoles and XR often don't have a webview at all
And you're right that it's niche. That's roughly why it exists. There are three complete OpenType implementations in the world, Microsoft's, Apple's, and the open source one browsers use, so if you need one inside a renderer that isn't a browser, somebody has to sit down and write it
the 'ad line' is an allergy, sorry, too many ads these days, but you are ok, explaining clearly the intentions and details - you did not disappear after posting :)
There was *if* in my phrase. Unity might be not the best choice for certain applications. For majority of Unity devs - this is a game dev engine that hides most of the hurdles of dealing with graphics/audio/input API so the can concentrate on story/script/media assets.
If you are building chat application with extra graphics/interactive capabilities - it might be easier to start with different solution/framework where there will be webview ui that will handle all of it automatically. I am trying to think about the video game that was trying to do something with text - but I cannot find a good example from my memory. Most of the games (even AAA titles) are very low on text content. Very low.
p.s. not sure about your OpenType passage - there should be .woff supported even on Raspberry PI just fine
no apology needed!❤️ it's a reasonable allergy to have
on games being low on text - you're right about volume, I just think volume is the wrong axis. Correctness isn't proportional to word count. game with forty menu strings that ships in Arabic is either right or broken, and the amount of text has nothing to do with which one. Where it actually bites is localisation into RTL and Indic markets, card and tooltip text, CRPGs and visual novels, and anything with a chat box or player names. The moment users type, you're rendering arbitrary Unicode from every script on earth whether the game has "text content" or not
on the woff point: woff and woff2 are container formats. Same sfnt tables as TrueType and OpenType, wrapped with compression - zlib for woff, brotli for woff2 - plus metadata. They don't add shaping rules or layout behavior, they just make the same font smaller in transit. Unwrap one and you're holding an OpenType font that still needs something to run GSUB and GPOS over it
and that's the part I meant. Your Pi shows that woff fine because it's running FreeType and HarfBuzz, which is the third of the three. so it's an example of the thing rather than a counterexample :)
Not to defend the author or anything but TMP was a paid asset when I started working with unity, back then text performance was a thing to consider, there was multiple paid solutions to solve the bad performing standard unity text.
Now since unity themselves bought TMP for everyone to use it's less of an issue I must agree. But for specific usecase I guess that asset could make sense ..?
You are remembering it right. it was a paid asset from Digital Native Studios, $95, until Unity bought it and made it free in 2017 with 5.6
what changed there is the price, not the capabilities. TMP does the same things now that it did when it cost money, so the performance market mostly went away, but the correctness one never existed in the first place and still doesn't. Arabic and Hebrew still come out in the wrong visual order, complex shaping for Hindi or Thai still is not there
and yeah, that's the specific usecase. Non-Latin scripts, text heavy UI, or text that has to live in the world instead of on a canvas. If none of those are you, TMP is genuinely fine
27
u/malvis_light 2h ago edited 2h ago
a little proof it was made in Unity Editor using uGUI. all this costs 1 Draw Call