# U2 · Unity-Spielwelt Stand: 30. September 2026. | Teil | Inhalt | Zustand | | --- | --- | --- | | U2A | Blender→FBX-Pipeline, sechs repräsentative Assets vollständig geprüft | **fertig** | | U2B | Weltgeometrie (G1-Karte, Türme, Ancients, Grotte, Aufstellungsbereiche), Materialsystem | offen | | U2C | Simulation/Darstellung: fester Takt, Interpolation, Bildraten-Unabhängigkeit | offen | | U2D | spielbare Unity-Partie, Vertical Function Test | offen | Voraussetzung U1.5 ist erfüllt ([U1.5-UNITY.md](U1.5-UNITY.md)). ## Ziel Die bestehende Partie läuft sichtbar in Unity (URP). Das ist noch keine grafische Neugestaltung; die kommt erst mit U5. Zuerst kommen: - die G1-Drei-Lane-Karte, - die G2-Türme (Grenzwacht, Bastion, Kernwacht), - die G2-Ancients, - die Bossgrotte und die Schlundkrone, - repräsentative vorhandene Einheiten. ## Vorgaben - **Adapter:** Unity treibt `LuneMatch` im festen Takt (0,05 s) über einen Akkumulator, unabhängig von der Bildrate. Ansichten lesen nur; sie schreiben nie in die Regeln. Beispiel: `Gebäude-HP = 0` führt zu Einsturz und Ruine, nie umgekehrt eine Animation zu einer Regelwirkung. - **Gemeinsames Materialsystem** (URP): Stein, Metall, Holz, Vegetation, Kristall, Runen, Wasser. Die G2-Shader aus Godot (stone, metal, crystal, rune, cloth, vein, water_glow, hide) dienen als fachliche Vorlage. - **Assets:** Quelle sind die Blender-Dateien und Generatoren im Referenz-Repository. Ein zentraler, reproduzierbarer Blender-Export erzeugt FBX; GLB nur, wo keine bearbeitbare Quelle existiert. - **Reihenfolge:** Erst sechs repräsentative Assets vollständig prüfen, dann die Welt und eine vollständige Bot-Partie. Den Batchlauf über alle Assets gibt es erst nach dem Vertical Function Test. ## U2A · Blender→FBX-Pipeline ### Aufbau | Datei | Aufgabe | | --- | --- | | `tools/blender/export_manifest.json` | Asset-Liste: Blender-Quelle, Art (statisch, starre Teile, Skelett), Exportregeln und Verweis auf den Godot-Manifesteintrag des GLB, das die Referenz benutzt | | `tools/blender/lune_fbx_export.py` | Blender im Hintergrund: Quelle öffnen, Regeln anwenden, prüfen, FBX schreiben, FBX wieder einlesen und erneut prüfen | | `tools/blender/export_fbx.sh` | Einstieg; macht die FBX-Dateien byteidentisch reproduzierbar | | `Assets/Luneraria/Art//.fbx` und `.export.json` | Ergebnis: Modell und Protokoll (Blender-Fakten und Prüfungen) | | `Assets/Luneraria/Editor/Art/LuneModelPostprocessor.cs` | Importregeln in Unity | | `Assets/Luneraria/Editor/Art/LuneAssetVerifier.cs` | Unity-Prüfung jedes importierten Modells gegen das Blender-Protokoll | | `Assets/Luneraria/Editor/Art/LuneAssetPreview.cs` | Vorschaubilder in URP | ```bash sh tools/blender/export_fbx.sh ``` ```bash /Applications/Unity/Hub/Editor/6000.3.20f1/Unity.app/Contents/MacOS/Unity -batchmode -projectPath "$PWD" -executeMethod Luneraria.EditorTools.LuneAssetVerifier.VerifyAll -logFile - ``` Weitere Einstiege: `LuneAssetVerifier.ReimportArt` (nach geänderten Importregeln) und `LuneAssetPreview.RenderAll`. ### Exportregeln Die Regeln wiederholen, was die Godot-Pipeline beim GLB-Export getan hat. Sonst entstünde ein anderes Modell: - **Phase-4-Einheiten:** Die Modifikatoren „HIGH RES“ (Unterteilung und Mikrorelief) kamen erst *nach* dem Laufzeitexport in die `.blend`-Datei. Sie werden nicht angewendet (bei `g01`: 36 Stück). - **Logische Namen:** Die Namen stammen aus den Eigenschaften `part_name` und `material_name`; Blender hatte teils Suffixe wie `.004` ergänzt. - **Figuren mit Skelett:** Die `.blend`-Datei ist vor dem Zusammenfügen gespeichert. Der Export fügt die Teile wie in Godot zu einem Skin-Mesh zusammen (Funkenlanze: 104 Teile → `FunkenBody`). - **Achsen:** Die FBX-Datei behält Blenders Z-oben-Achsen; Unity rechnet sie beim Import mit „Bake Axis Conversion“ um, also ohne Wurzelrotation. Blender (x, y, z) wird dabei Unity (x, z, y); die Vorderseite (Blender −Y) läge auf Unity −Z. - Deshalb dreht der Export jedes Asset vorher um 180° um die Hochachse und wendet die Drehung an. Danach gilt Unity = (−x, y, z) der Godot-/glTF-Koordinaten, und die Vorderseite liegt auf +Z wie in Godot. - Blenders „Apply Transform“ ist für Skelette als fehlerhaft dokumentiert und wird nicht benutzt. - **Maßstab und Inhalt:** 1 Blender-Einheit = 1 m; Normalen, Tangenten (MikkTSpace, wo UVs existieren), lineare Vertexfarben; nur Deform-Bones, keine Leaf-Bones; jede Action wird ein Clip. - **Reproduzierbarkeit:** Blenders FBX-Schreiber stempelt die Uhrzeit ein und leitet Objekt-IDs aus Pythons String-Hash ab. Der Export fixiert beides (feste Uhrzeit, `PYTHONHASHSEED=0` mit `--python-use-system-env`). Zwei Läufe liefern byteidentische FBX-Dateien und identische Protokolle. ### Prüfungen Blender-Seite, vor und nach dem Schreiben (Rundreise durch einen FBX-Import): | Prüfpunkt | Wie | | --- | --- | | Einheiten, Maßstab | metrisch, `scale_length` 1, keine Objektskalierung, keine negative Skalierung | | Achsen, Vorderseite | Drehung angewendet; Vorwärtsmarker (Phase 4: Empty `Forward`) liegt in Unity auf +Z | | Mesh-Namen | eindeutig; gleich den Knoten des Godot-GLB | | Dreiecke | gleich dem Godot-GLB, auch nach dem Wiedereinlesen | | Materialslots | keine leeren Slots; Materialien gleich dem Godot-GLB | | Normalen | Einheitslänge an allen Ecken | | Tangenten | Voraussetzungen (UVs, keine N-Ecke); Meshes ohne UVs sind vermerkt und werden triplanar oder unbeleuchtet schattiert | | Maße | Ruhelage gleich den `bounds_godot` des Godot-Manifests (Türme und Ancient: ohne Schadens- und Ruinenteile, wie dort gemessen) | | Skelett | genau eine Armature, ein Root Bone `Root`, Bone-Namen und -Anzahl wie im Godot-GLB, portable Namen | | Clips | Namen und Längen wie im Godot-GLB; Pflichtclips vorhanden; Loop-Flag und Kontaktzeit aus den Action-Eigenschaften | | Blend Shapes | keine in den Quellen | Unity-Seite (`LuneAssetVerifier`, gegen das Blender-Protokoll): | Prüfpunkt | Wie | | --- | --- | | Importregeln | Maßstab 1, Dateieinheiten, Achsen-Bake, Normalen und Tangenten aus der Datei | | Achsen | Wurzel und alle Nicht-Bone-Knoten ohne Rotation und Skalierung | | Mesh-Namen, Dreiecke | Menge und Anzahl je Mesh gleich | | Maße | aus den Vertices berechnet, Abweichung höchstens 2 mm; gemessen höchstens 0,05 mm | | Materialslots | Namen je Renderer gleich den Blender-Slots | | Normalen, Tangenten, UVs, Vertexfarben | vorhanden und gültig, wo Blender sie hat; Tangenten mit w = ±1 | | Vorderseite | Vorwärtsmarker auf +Z | | Skelett | Root Bone, Bone-Namen, gültiger Generic-Avatar | | Clips | Namen, Längen (auf einen halben Frame genau), Loop-Flags, Kontakt-Events (`OnLuneContact`) | ### Ergebnis: sechs repräsentative Assets und drei Szenenbauten | Asset | vertritt | Dreiecke (= Godot-GLB) | Blender-Prüfungen | Unity-Prüfungen | | --- | --- | ---: | --- | --- | | `g01` Kohlenbeißer | normale Einheit, 131 benannte Teile | 79.780 | 18/18 | 14/14 | | `funkenlanze` | Einheit mit Skelett (Held), 26 Bones, 9 Clips | 24.036 | 26/26 | 18/18 | | `grenzwacht` | Turm (mit Schadens- und Ruinenteilen) | 6.516 | 18/18 | 13/13 | | `ancient` Mondherz | Ancient | 19.032 | 18/18 | 13/13 | | `schlundkrone` | Schlundkrone (Boss), 24 Bones, 11 Clips | 5.712 | 28/28 | 18/18 | | `map_props` | Vegetation und Kartenrequisiten (Eichen, Kiefern, Sträucher, Felsen, Brücke, Randsteine) | 7.338 | 14/14 | 13/13 | | `bastion`, `kernwacht`, `bossgrotte` | für die Szene in U2B (Innen- und Basisturm, Mondschlund) | 9.364, 9.224, 15.182 | je 18/18 | je 13/13 | Summe: 176 Blender-Prüfungen und 128 Unity-Prüfungen, alle bestanden. Protokolle: - `Assets/Luneraria/Art/*/*.export.json` (Blender). - `docs/port/logs/u2a/unity-verify.json` (Unity). Bilder unter `docs/port/screenshots/u2a/`: - je Asset eine Ansicht von vorn-rechts, - die Grenzwacht zusätzlich als Ruine, - Funkenlanze und Schlundkrone zusätzlich im Kontaktframe von `attack_a` (Clips laufen). ### Bekannte Grenzen - **Materialien:** Die Vorschau benutzt URP-Lit-Materialien, die Unity aus den FBX-Materialbeschreibungen erzeugt (Blender-Palettenfarben). Das eigentliche Materialsystem (Stein, Metall, Kristall, Runen, Stoff, Wasser; Teamfarben; Vertex-AO) folgt in U2B. - Stoff (Wimpel, Banner) ist einseitig modelliert und braucht dort doppelseitiges Rendern; in der Vorschau fehlt er deshalb. - **Ohne UVs:** Diese Meshes haben keine Tangenten (Unity meldet das beim Import): Kristalle, Trümmer, Felsen, Kartenrequisiten und einige Phase-4-Kleinteile. Sie brauchen triplanare oder unbeleuchtete Materialien. - **Starre Einheiten:** Die Phase-4-Einheiten werden in Godot aus benannten Teilen prozedural animiert. Die Teile kommen mit, die Animation folgt mit den Einheitenansichten. - **Größe:** Die FBX-Dateien liegen direkt im Repository (9 Dateien, 16 MB). Für den Batchlauf über alle Assets ist Git LFS zu erwägen. ### Batchlauf (nach dem Vertical Function Test) Das Manifest enthält bisher die 9 Assets der Szene. Die übrigen Assets kommen erst nach U2D in das Manifest und werden dann mit denselben Regeln und Prüfungen exportiert: - 58 weitere Phase-4-Modelle. - 5 Figuren mit Skelett. - 7 Völker-Modelle. Für Zwerg und Troll fehlt die `.blend`-Datei im Referenz-Repository; sie entsteht aus dem Generator `build_peoples.py`. Bauten aus einer GLB ohne Quelle folgen nur nach Einzelfallprüfung. ## U2B bis U2D Folgen in diesem Dokument. ## Abnahme (gesamt) - Die Partie läuft sichtbar. - Die Kamera entspricht der Godot-Kamera. - Screenshots neben den Godot-G2-Bildern mit vergleichbarer Kamera. - Leistung gemessen, einschließlich Mono-Simulationszeit. - Bekannte Unterschiede dokumentiert. - Commits U2A bis U2D auf `luneraria/u2`.