G1-Karte in Unity (Assets/Luneraria/Scenes/G1_Map.unity), reproduzierbar gebaut aus dem Godot-Weltgenerator (gebacken), den FBX-Modellen aus U2A und der Karte des C#-Kerns. - tools/godot-golden/world_export.gd: backt Gelände (Raster, Farben, Lauf- und Standhöhen), Lanebeläge, Plattform, Brücke, Randsteine, Basen, Landmarken, Vegetation, Adern, Grottentreppen, Aufstellungsbereiche und Licht. Braucht einen echten Renderer (HEADLESS=0); prüft auf Headless-Einheitstransformationen. - LuneWorldBuilder: Meshes (GUID-stabil), Szene, Licht, Himmel, Post-Processing, 16 Türme, 2 Ancients und die Grotte aus LuneMap mit Teammaterialien. - Materialsystem: Luneraria/Surface (Gelände, Kluft-Oberflächen, Fluss, Adern, Kristall, G2-Werte mit Teamvarianten und Vertex-AO) und Luneraria/Pad; LuneMaterialSet.Dress wie Godots dress. - View-Assembly: LuneSpace (Unity = (-x, h, y)), LuneGround, LuneCameraMath, LuneBuildingView (Zustände intakt bis Ruine). - Vergleichsbilder mit den Kameraeinstellungen der Godot-G2-Aufnahmen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
230 lines
15 KiB
Markdown
230 lines
15 KiB
Markdown
# 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 | **fertig** |
|
||
| 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/<Gruppe>/<id>.fbx` und `<id>.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 · Weltgeometrie
|
||
|
||
### Quellen
|
||
|
||
Die Szene `Assets/Luneraria/Scenes/G1_Map.unity` entsteht reproduzierbar aus drei Quellen, ohne Handarbeit:
|
||
|
||
| Quelle | liefert | Weg nach Unity |
|
||
| --- | --- | --- |
|
||
| Godot-Generator der G1-Welt (`lune_world.gd`, `lune_terrain.gd`) | Gelände, Wasser, Lanebeläge, Plattform, Brücke, Randsteine, Basen, Landmarken, Vegetation, Adern, Grottentreppen, Aufstellungsbereiche, Licht | `tools/godot-golden/world_export.gd` backt die Welt nach `Assets/Luneraria/World/Bake/` (JSON und Binärdaten); `LuneWorldBuilder` baut daraus Meshes und Szene |
|
||
| Blender-Pipeline (U2A) | Türme, Ancients, Grotte, Requisiten | FBX-Modelle, in der Szene als Prefab-Instanzen |
|
||
| C#-Kern | Gebäude-IDs, Positionen, Ausrichtung | `LuneMap` direkt; die Szene enthält keine eigenen Kartendaten |
|
||
|
||
Warum gebacken statt portiert:
|
||
- Gelände und Vegetation hängen an Godots FastNoiseLite und Zufallsgenerator. Ein Nachbau wäre nicht nachweisbar exakt; der Bake ist es.
|
||
- Es gibt für diese Welt keine Blender-Quelle; ihre Quelle ist der Generator. Der Bake ist dessen reproduzierbarer Export, kein GLB-Umweg.
|
||
- U5 bekommt ohnehin eine neue Weltquelle.
|
||
|
||
```bash
|
||
HEADLESS=0 sh tools/godot-golden/run_godot.sh world_export --out="$PWD/Assets/Luneraria/World/Bake"
|
||
```
|
||
|
||
```bash
|
||
/Applications/Unity/Hub/Editor/6000.3.20f1/Unity.app/Contents/MacOS/Unity -batchmode -projectPath "$PWD" -executeMethod Luneraria.EditorTools.LuneWorldBuilder.BuildScene -logFile -
|
||
```
|
||
|
||
Der Bake braucht einen echten Renderer (`HEADLESS=0`). Godots Headless-Renderer liefert für MultiMesh-Instanzen Einheitstransformationen; so lag im ersten Versuch die ganze Vegetation im Kartenmittelpunkt. Das Werkzeug bricht jetzt ab, wenn es so einen Bake erkennt.
|
||
|
||
### Inhalt
|
||
|
||
| Teil | Umfang |
|
||
| --- | --- |
|
||
| Gelände | 121 × 121 Punkte (1 m) plus Bergring 67 × 67 (4 m), Zonenfarbe und Felsanteil als Vertexfarbe, Dreiecksmuster wie in Godot |
|
||
| Welt | 59 Knoten: 35 Einzelmeshes, 98 MultiMesh-Instanzen (Randsteine ausgenommen), 532 Requisiten (372 Vegetation und Felsen, 159 Randsteine, Brücke) |
|
||
| Bauten | 16 Türme (Grenzwacht, Bastion, Kernwacht), 2 Ancients, Bossgrotte; Positionen und Blickrichtung aus dem Kern; Teammaterialien |
|
||
| Aufstellungsbereiche | 3 je Team und Grotteneingänge, ausgeblendet (Planungsphase schaltet sie ein) |
|
||
| Höhen | `LuneGround`: Lauf-Höhe (1-m-Raster) und Standhöhe mit Plaza, Stufen und Grottenterrasse (0,5-m-Raster) für Figuren |
|
||
| Licht | Sonne und Aufhellung aus dem Bake, flaches Umgebungslicht, prozeduraler Himmel, ACES, Bloom, Kontrast/Sättigung wie `lighting.gd`; kein Nebel (wie in Godot) |
|
||
|
||
Koordinaten: Unity = (−x, Höhe, y) der Kartenpunkte. Mit dem Wechsel der Händigkeit bleiben Bild und Vorderseiten der Dreiecke erhalten; die Indexfolge bleibt deshalb unverändert. Gemeinsame Umrechnung: `Assets/Luneraria/View/LuneSpace.cs`.
|
||
|
||
Reproduzierbarkeit:
|
||
- Der Bake ist deterministisch (Godot-Generator mit festen Seeds).
|
||
- Der Builder aktualisiert Meshes und Materialien an Ort und Stelle; ihre GUIDs bleiben über Builds gleich.
|
||
- Nur die Datei-IDs der Szenenobjekte wechseln; das ist bei per Skript erzeugten Szenen unvermeidlich.
|
||
|
||
### Materialsystem
|
||
|
||
Alle Materialien verwenden `Luneraria/Surface` (URP, HLSL, SRP-Batcher-fähig) oder `Luneraria/Pad`. Portiert sind:
|
||
- das Gelände (`lune_terrain.gdshader`),
|
||
- die Kluft-Oberflächen (`sanctuary.gdshader`: Stein, Pflaster, Erde, Rinde, Laub mit Wind),
|
||
- der Fluss (`river.gdshader`),
|
||
- die Energieadern (`lune_vein.gdshader`),
|
||
- die Aufstellungsbereiche (`lune_pad.gdshader`).
|
||
|
||
Mit dabei sind jeweils triplanarer Kalkstein und Relief aus Bildschirmableitungen, wie in Godot.
|
||
|
||
Die G2-Oberflächen (`LN_*`) haben Werte und Teamvarianten aus `lune_materials.gd`: Kristall, Rune, Teammetall, Stoff; Blau, Rot und neutral. Vertex-AO wird mit verrechnet. `LuneMaterialSet.Dress` tauscht die Importmaterialien wie Godots `dress` gegen die geteilten Materialien.
|
||
|
||
Vereinfacht gegenüber Godot, bis U5 die Oberflächen neu macht:
|
||
- Quaderfugen der Steinshader, Runenglyphen (stattdessen ein schwach leuchtendes Band), Kristalltiefe, Stoffembleme.
|
||
- Beschädigungs- und Einsturzparameter der Materialien.
|
||
|
||
Befund beim Einrichten: Unity reicht `[HDR]`-Farben unverändert als linear weiter, gewöhnliche Farben konvertiert es aus Gamma. Das war am blassen Kristall zu sehen. Emission wird deshalb als linearer Wert gesetzt (`LuneMaterialFactory.Hdr`).
|
||
|
||
### Vergleich mit Godot
|
||
|
||
`LuneWorldCapture.CaptureAll` fotografiert die Szene mit den Kameraeinstellungen der Godot-G2-Aufnahmen (`g2_views.gd`: Fokus, Zoom, Drehung; Kamera wie `lune_camera.gd`). Die Bilder liegen unter `docs/port/screenshots/u2b/`, das Gegenstück unter `../saumwacht-godot/docs/luneraria/screenshots/g2/nachher/`.
|
||
|
||
| Bild | Befund |
|
||
| --- | --- |
|
||
| `15-gesamtkarte` | Anordnung gleich: Blau unten links, Rot oben rechts, Grotte links, Kluft von der Quelle unter der Plattform zum Delta mit Brücke; Waldinseln, Randsteine, Mauern, Runensteine an denselben Stellen |
|
||
| `01-ancient-100`, `07-basistuerme` | Ancient und Basistürme in gleicher Lage und Ausrichtung, Teamfarben richtig |
|
||
| `05-tower1-grenzwacht`, `06-tower2-bastion` | Turm, Tür, Wimpel, Randsteine und Plattformsteine decken sich im Bildausschnitt |
|
||
| `10-grotte` | Arena, Tor, Säulen und Treppen gleich; der schlafende Boss und die Grottenzustände kommen mit der Anbindung (U2C/U2D) |
|
||
|
||
Unterschiede:
|
||
- Godot zeigt in allen Bildern das HUD (U3) und in der Planungsphase die Aufstellungsbereiche.
|
||
- Die Materialien sind vereinfacht (siehe oben).
|
||
- Die Beleuchtung ist ähnlich, aber nicht identisch abgestimmt.
|
||
|
||
## U2C 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`.
|