Support

Häufig gestellte Fragen

Klare Antworten zu Build-Größe, Schriften, Glyphen-Atlas und Laufzeit-Performance — destilliert aus echten Entwicklerfragen.

Build-Größe & Distribution

Bläht UniText meine Build-Größe auf? Was landet eigentlich im Build?

Nein. UniText backt keine Textur-Atlanten pro Schrift in deinen Build. Glyphen werden zur Laufzeit in einen gemeinsamen Atlas (auf Texture2DArray-Basis) gerastert, mit Referenzzählung pro Glyph und LRU-Verdrängung. Nur die Schriftdaten kommen in deinen Build — niemals Atlanten. Obendrein verkleinert die integrierte Schriftkomprimierung (Zstd, Level 22) die Schriftdaten für Latein/Arabisch um bis zu ~2.7× (bei CJK bescheidener, ~1.3×).

Muss ich die .ttf-Dateien behalten und mit ausliefern?

Nein. Das UniTextFont-Asset bettet die Schrift-Bytes in sich selbst ein. Die Referenz auf die Ausgangsschrift existiert nur im Editor (in #if UNITY_EDITOR gekapselt) — in einem Player-Build gibt es sie schlicht nicht, sie ist also keine Laufzeitabhängigkeit und wird nicht über die Abhängigkeitsauflösung in ein AssetBundle gezogen. Du kannst die .ttf löschen, sobald das Asset erstellt ist.

Muss ich die .ttf überhaupt in mein Projekt importieren?

Nein. Du kannst ein UniTextFont aus einer .ttf erstellen, die irgendwo auf deiner Festplatte liegt — über das UniText-Tool-Fenster (der Dateidialog liest die Bytes direkt). Die Schrift ins Projekt zu importieren ist optional.

Wie viel fügt UniText einem leeren Build tatsächlich hinzu?

• WebGL: Ein leerer Build ist ≈ 6–10 MB (variiert je nach Unity-Version und installierten Paketen); UniText fügt seine nativen Bibliotheken hinzu (HarfBuzz, FreeType). Das sind dieselben Industriestandard-Bibliotheken, die auch Unitys eigener UI Toolkit Advanced Text Generator mitbringt — nichts Exotisches (UniText trägt lediglich seine eigenen Kopien). • Android: Ein APK mit zwei Architekturen enthält beide — etwa +4 MB pro Architektur. Aber wenn du ein AAB veröffentlichst, liefert Google Play ein gerätespezifisches Bundle aus, sodass der Nutzer nur seine eigene Architektur herunterlädt (~4 MB), nicht beide.

Wie schlägt sich UniText gegenüber TextMesh Pro bei CJK oder großen Schriften?

Mit TMP im Static-Atlas-Population-Modus bläht das Backen des vollständigen Glyphensatzes einer typischen CJK-Schrift den Build um Dutzende bis Hunderte MB auf (mehrere 4096²/8192²-Atlanten; rechne mit ~80–250 MB je nach Glyphenanzahl und Auflösung). Der springende Punkt: UniTexts Overhead skaliert nicht mit der Glyphenanzahl — es sind dieselben paar MB, egal ob du Latein oder volles CJK auslieferst.

Kann ich Schriften dynamisch von einem Server oder CDN laden?

Ja — das liegt auf der Seite des Entwicklers, und UniText steht dir nicht im Weg. Lade die Schrift-Bytes mit deinem eigenen Code herunter (UnityWebRequest) und erstelle daraus zur Laufzeit ein UniTextFont via CreateFontAsset(byte[]). Um eine Schrift auf genau die Zeichen zu reduzieren, die du brauchst (Subsetting), nutze das Build-Zeit-Tool von UniText. Es gibt keinen eingebauten CDN-Auto-Loader im Paket — das ist bewusst die Verantwortung des Projekts, nicht der Engine.

Schriften & Systemschriften

Kann UniText die System-Schrift des Betriebssystems nutzen? Was kostet das an Speicher und Startzeit?

Ja — SystemFont liest die Schriftdatei zur Laufzeit direkt vom Betriebssystem, hat also keinen Einfluss auf die Build-Größe (nichts wird gebacken). Die Auflösung erfolgt verzögert (bei der ersten Nutzung), sodass sie den App-Start nicht verlangsamt.

Unterstützt WebGL Systemschriften?

Nein — und das ist eine Einschränkung des Browsers, keine von UniText. Die Browser-Sandbox gibt keine Schriften des Betriebssystems preis. Bette für WebGL eine Schrift in ein UniTextFont-Asset ein (oder lade die Bytes selbst — siehe die CDN-Frage oben).

Glyphen-Atlas — SDF Detail & Tile Size

Was machen „SDF Detail“ und „Tile Size Offset“ eigentlich?

Glyphen liegen in Kacheln von drei Größen — 64, 128, 256 — und die Größe ergibt sich aus der Kontur-Komplexität (viele Segmente → 128/256, eine einfache Kontur → 64). • SDF Detail (Detailgrad) ist ein Multiplikator auf die Komplexitätsschätzung. Erhöhe ihn, und ein ohnehin nicht-triviales Glyph wandert eher in eine größere Kachel. (Eine wirklich einfache Form bleibt bei 64 — der Multiplikator wirkt nur auf Glyphen oberhalb des Schwellenwerts.) • Tile Size Offset (Kachelgrößen-Versatz) ist ein harter Schritt entlang der Größenleiter (gewählt 64 + Versatz 1 → 128; Bereich −2..+2).

Welche der beiden sollte ich für die Performance priorisieren?

Keine für sich allein — beide bestimmen nur die finale Kachelgröße, und die Kosten hängen allein von dieser Größe ab. Zwei Kombinationen, die zur selben Kachelgröße führen, kosten exakt gleich viel. Ziele auf die kleinste Kachelgröße, die noch akzeptable Qualität liefert.

Laufzeit-Performance

Wann rastert UniText Glyphen? Kopiert es jeden Frame Speicher?

Nur wenn ein Glyph noch nicht im Atlas ist — niemals pro Frame. Für „Hello world“ rastert es die eindeutigen Glyphen H e l o w r d. Ein zweites H bewirkt nichts; ein a rastert nur das a.

Warum gibt es einen kurzen Ruckler, wenn viel neuer Text auf einmal erscheint?

Die Kosten sind proportional zur Anzahl der eindeutigen, erstmals gesehenen Glyphen, die in diesem Frame gerastert werden — nicht zur Länge des Textes. In unserem Benchmark bedeuten ~2000 eindeutige Glyphen im ersten Frame ≈ 1 Sekunde auf einem typischen Android-Gerät; TMP und UI Toolkit brauchen im selben Szenario 10+ Sekunden. Die Wiederverwendung gecachter Glyphen ist kostenlos.

Ich sehe keinen UniText-Job im Profiler — funktioniert Multithreading überhaupt?

UniText verlässt sich auf dem Hot Path kaum auf das Unity Job System — bewusst so. Die Glyphen-Rasterung (unser proprietäres lpSDF / lpMSDF) läuft standardmäßig auf der GPU über einen Compute-Shader; Burst-Jobs sind nur der CPU-Fallback, wenn Compute nicht verfügbar ist. Das eigentliche Multithreading — Shaping, Layout, Mesh-Generierung — läuft auf UniTexts eigenem OS-Thread-Pool (nicht Unity Jobs, weshalb sie nicht im Jobs-Profiler auftauchen). „Kein UniText-Job“ heißt also nicht „Threads sind aus“: Entweder ging die Arbeit an die GPU, oder der Atlas ist bereits warm, oder der Text liegt unter der Parallelitätsschwelle (kurze oder einzelne Labels werden sequenziell verarbeitet — so ist es günstiger).

Schadet MonoBehaviour.Update() der Performance? Braucht man einen einzigen UniTextManager?

„Update() ist langsam“ ist ein Mythos für Release-Builds. Der Overhead des Magic-Method-Aufrufs aus nativem Code ist real, aber vernachlässigbar (~1000 Aufrufe ≈ 0.16 ms) — er ist nicht der Flaschenhals. Die eigentlichen Kosten in naivem Code sind das AoS-Speicherlayout, nicht der Callback selbst; UniText setzt SoA dort ein, wo es zählt (Unicode-Attribute, Metriken, Puffer pro Pixel). (Deshalb ist auch ECS schnell — wegen SoA, nicht wegen „ECS-Magie“.) Und UniText ist ohnehin zentralisiert — nur eben nicht als MonoBehaviour-Manager: Update() selbst ist nahezu leer, und die schwere Arbeit wird in einem einzigen gebündelten Durchlauf über die Render-Callbacks von Canvas gesammelt (was auch die komponentenübergreifende Parallelität ermöglicht).

Keine Antwort auf deine Frage gefunden?

Frag in unserem Discord — genau solche Fragen haben diese Seite geformt, und wir antworten meist schnell.