Raka svar om build-storlek, fonter, glyfatlasen och prestanda i runtime — destillerade ur verkliga frågor från utvecklare.
Nej. UniText bakar inte in texturatlaser per font i din build. Glyfer rastreras i runtime till en delad atlas (baserad på Texture2DArray) med referensräkning per glyf och LRU-utrensning. Bara fontdatan följer med i din build — aldrig atlaser. Utöver det krymper inbyggd fontkomprimering (Zstd, nivå 22) fontdata med upp till ~2.7× för latin/arabiska (CJK är mer blygsam, ~1.3×).
Nej. UniTextFont-assetet bäddar in fontens bytes i sig självt. Referensen till källfonten finns bara i Editorn (inkapslad i #if UNITY_EDITOR) — den existerar helt enkelt inte i en player-build, så den är inte ett runtime-beroende och dras inte in i en AssetBundle via beroendeuppslagning. Du kan radera .ttf-filen när assetet väl har skapats.
Nej. Du kan bygga en UniTextFont från en .ttf var som helst på din disk via UniText-verktygsfönstret (fildialogen läser byten direkt). Att importera fonten till projektet är valfritt.
• WebGL: en tom build är ≈ 6–10 MB (det varierar med Unity-version och installerade paket); UniText lägger till sina nativa bibliotek (HarfBuzz, FreeType). Det är samma branschstandardbibliotek som Unitys egen UI Toolkit Advanced Text Generator levererar — inget exotiskt (UniText bär bara med sig sina egna kopior). • Android: en APK med två arkitekturer bär med sig båda — cirka +4 MB per arkitektur. Men när du publicerar en AAB levererar Google Play ett enhetsspecifikt paket, så användaren laddar bara ner sin egen arkitektur (~4 MB), inte båda.
Med TMP i läget Static atlas-population sväller inbakning av hela glyfuppsättningen för en typisk CJK-font upp bygget med tiotals till hundratals MB (flera 4096²/8192²-atlaser; räkna med ~80–250 MB beroende på antal glyfer och upplösning). Det viktiga: UniTexts overhead skalar inte med antalet glyfer — det är samma få MB oavsett om du levererar latin eller full CJK.
Ja — det ligger på utvecklarens sida, och UniText står inte i vägen. Ladda ner fontens bytes med din egen kod (UnityWebRequest) och bygg en UniTextFont av dem i runtime via CreateFontAsset(byte[]). För att trimma ner en font till bara de tecken du behöver (subsetting) använder du UniTexts build-time-verktyg. Det finns ingen inbyggd CDN-autoladdare i paketet — det är medvetet projektets ansvar, inte motorns.
Glyfer ligger i tiles i tre storlekar — 64, 128, 256 — och storleken väljs utifrån konturkomplexitet (många segment → 128/256, en enkel kontur → 64). • SDF Detail är en multiplikator på komplexitetsuppskattningen. Höj den så är det mer sannolikt att en redan icke-trivial glyf flyttas upp till en större tile. (En genuint enkel form stannar på 64 — multiplikatorn påverkar bara glyfer över tröskeln.) • Tile Size Offset är ett hårt steg längs storleksstegen (vald 64 + offset 1 → 128; intervall −2..+2).
Ingen av dem för sig — båda avgör bara den slutliga tile-storleken, och kostnaden bestäms enbart av den storleken. Två kombinationer som landar på samma tile-storlek kostar exakt lika mycket. Sikta på den minsta tile-storlek som fortfarande ger acceptabel kvalitet.
Bara när en glyf inte redan finns i atlasen — aldrig per frame. För ”Hello world” rastreras de unika glyferna H e l o w r d. Ett andra H gör ingenting; ett a rastrerar bara a:et.
Kostnaden är proportionell mot antalet unika glyfer som ses för första gången och rastreras den framen — inte mot textens längd. I vårt benchmark tar ~2000 unika glyfer på första framen ≈ 1 sekund på en typisk Android-enhet; TMP och UI Toolkit tar 10+ sekunder i samma scenario. Att återanvända cachade glyfer är gratis.
UniText förlitar sig knappt på Unity Job System på hot path — helt avsiktligt. Glyfrastrering (vår egenutvecklade lpSDF / lpMSDF) körs som standard på GPU:n via en compute shader; Burst-jobb är bara CPU-fallbacken när compute inte är tillgängligt. Den huvudsakliga multitrådningen — shaping, layout, mesh-generering — körs på UniTexts egen OS-trådpool (inte Unity Jobs, vilket är varför de inte dyker upp i Jobs-profilern). Så ”inget UniText-jobb” betyder inte ”trådarna är avstängda”: antingen gick arbetet till GPU:n, eller så är atlasen redan varm, eller så är texten under parallelismtröskeln (korta eller enskilda etiketter behandlas sekventiellt — det är billigare så).
”Update() är långsamt” är en myt för release-builds. Overheaden för anropet av magic-metoden från nativ kod är verklig men försumbar (~1000 anrop ≈ 0.16 ms) — det är inte flaskhalsen. Den verkliga kostnaden i naiv kod är AoS-minneslayout, inte callbacken i sig; UniText tillämpar SoA där det spelar roll (Unicode-attribut, metrics, per-pixel-buffertar). (Det är också därför ECS är snabbt — tack vare SoA, inte ”ECS-magi”.) Och UniText är centraliserat ändå — bara inte som en MonoBehaviour-manager: Update() i sig är nästan tomt, och det tunga arbetet samlas i ett enda batchat pass på Canvas render-callbacks (vilket också är det som ger parallelism mellan komponenter).
Fråga i vår Discord — frågor som dessa är precis vad som format den här sidan, och vi svarar oftast snabbt.