Files
svenm_adminandClaude Sonnet 5 2fd424b2bf chore: add project scaffolding, third-party assets and settings
- Terrain, Prefabs, Textures, Modelle (u. a. Lieferkarton-/Vibrations-
  Rohdaten in Assets/Data)
- Third-Party-Pakete: TextMesh Pro, Toby Fredson Foliage Engine, Sat
  Productions Street Lights, ProBuilder Data
- Neue Szene Boot.unity, Shop-Szenenordner
- Package-Manifest/Lock, ProjectSettings, Build-Profile, .slnx
- Doku: EDITOR_SETUP.md, INSTALL.md, TODO.md

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 19:22:02 +02:00

217 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Editor-Setup (Meilenstein 0)
Schritt-für-Schritt-Anleitung für die manuelle Editor-Arbeit aus
`docs/ROADMAP.md`, Meilenstein 0: Szenen, Prefabs, NetworkManager.
Referenz für Inspector-Feldnamen: Unity zeigt `_camelCase`-Felder ohne
Unterstrich und mit Leerzeichen an (`_catalog`**Catalog**,
`_customerMask`**Customer Mask**).
---
## 0. Ordner anlegen
Im Project-Fenster unter `Assets/`:
- `Assets/Scenes`
- `Assets/Prefabs`
- `Assets/Data` (falls noch nicht vorhanden)
Rechtsklick auf `Assets``Create > Folder`, jeweils benennen.
## 1. Platzhalter-Produktkatalog
Die Prefabs unten haben alle ein `Catalog`-Feld, das nicht leer sein darf
(sonst NullReferenceException zur Laufzeit). Vollständige Produkte kommen
später — jetzt nur ein leeres Katalog-Asset, damit referenziert werden kann:
1. Rechtsklick auf `Assets/Data``Create > AfterHours > Product Catalog`
2. Benennen: `ProductCatalog`
Später Produkte anlegen (`Create > AfterHours > Product`) und in die
`Products`-Liste dieses Assets ziehen.
## 2. Layer "Customer" anlegen
Wird von `CustomerAgent` gebraucht (Personal-Space-Check per `OverlapSphere`).
1. `Edit > Project Settings > Tags and Layers`
2. Unter „Layers" eine freie User-Layer-Zeile (z. B. 6) mit `Customer` beschriften
---
## 3. Player-Prefab
1. `GameObject > Create Empty`, benennen `Player`
2. Component: `Character Controller` (wird von `PlayerAvatar` per `RequireComponent` verlangt)
3. Component: `Network Object`
4. Component: `PlayerAvatar` (aus `AfterHours.Networking`)
5. Component: `PlayerInteractor` (aus `AfterHours.Interaction`)
6. Component: `PlayerHands` (aus `AfterHours.Networking`)
7. Component: `Network Transform` — repliziert Position an andere Clients (für Solo-Host-Test egal, aber für Meilenstein 2 nötig)
8. Kind-Objekt für die Kamera: Rechtsklick auf `Player` → Kamera erstellen, benennen `CameraRoot`, auf Kopfhöhe positionieren (z. B. Y = 1,6)
- `CameraRoot` in **beiden** Feldern eintragen: `PlayerAvatar.Camera Root` und `PlayerInteractor.Eyes`
9. Werte grob: `Walk Speed` 3.4, `Mouse Sensitivity` 2, `Reach` 2.5 (Defaults reichen)
10. `Interactable Mask` auf „Everything" lassen
11. Als Prefab nach `Assets/Prefabs` ziehen, Szenen-Objekt löschen
## 4. Customer-Prefab
1. `GameObject > Create Empty`, benennen `Customer`
2. Layer des Objekts auf `Customer` setzen
3. Component: `Nav Mesh Agent`
4. Component: `Capsule Collider` (Radius ~0.3, Height ~1.8) — ohne Collider erkennen sich Kunden nicht gegenseitig
5. Component: `Network Object`
6. Component: `Network Transform` (Server bewegt den Agent, muss an Clients repliziert werden)
7. Component: `CustomerAgent` (aus `AfterHours.Customers`)
8. `Catalog``ProductCatalog`-Asset
9. `Customer Mask` → Layer `Customer`
10. Optional: Platzhalter-Body (Capsule-Mesh als Kind), rein kosmetisch
11. Als Prefab nach `Assets/Prefabs` ziehen, Szenen-Objekt löschen
## 5. ShelfSlot-Prefab
1. `GameObject > Create Empty`, benennen `ShelfSlot`
2. Component: `Box Collider` (z. B. 0.5 × 0.8 × 0.4) — für den Blick-Raycast von `PlayerInteractor`
3. Component: `Network Object`
4. Component: `ShelfSlot` (aus `AfterHours.Shop`)
5. `Catalog``ProductCatalog`-Asset
6. `Capacity Units` Default (12) lassen
7. `Exposed To Street` nur bei vom Schaufenster sichtbaren Regalen anhaken (pro platzierter Instanz individuell)
8. `Display Root` optional (aktuell nur `// TODO` im Code)
9. Als Prefab nach `Assets/Prefabs` ziehen, Szenen-Objekt löschen
## 6. CashRegister-Prefab
1. `GameObject > Create Empty`, benennen `CashRegister`
2. Component: `Box Collider`
3. Component: `Network Object`
4. Component: `CashRegister` (aus `AfterHours.Shop`)
5. Kind-Objekt `QueueStart` (leeres Transform), vor der Kasse positioniert, `Forward`-Achse zeigt in Richtung der Warteschlange
6. `Catalog` → Asset, `Queue Start` → das `QueueStart`-Kind, `Queue Spacing` Default (0.8)
7. Als Prefab nach `Assets/Prefabs` ziehen, Szenen-Objekt löschen
## 7. StorageCrate-Prefab
1. `GameObject > Create Empty`, benennen `StorageCrate`
2. Component: `Box Collider`
3. Component: `Network Object`
4. Component: `StorageCrate` (aus `AfterHours.Shop`)
5. `Catalog` → Asset, `Product Id` → -1 bis ein echtes Produkt existiert (dann die ID eintragen), `Starting Quantity` Default (200)
6. Als Prefab nach `Assets/Prefabs` ziehen, Szenen-Objekt löschen
Pro Produkt später vermutlich mehrere `StorageCrate`-Instanzen im Backroom —
das Prefab ist die Vorlage, `Product Id` pro Instanz individuell setzen.
## 7b. OrderTerminal-Prefab
Bestellt beim Großhandel nach — fixes Produkt/Menge pro Instanz, kein UI-Menü.
1. `GameObject > Create Empty`, benennen `OrderTerminal`
2. Component: `Box Collider`
3. Component: `Network Object`
4. Component: `OrderTerminal` (aus `AfterHours.Shop`)
5. `Catalog` → Asset, `Product Id` → ID eines existierenden Produkts, `Order Quantity` Default (50)
6. Als Prefab nach `Assets/Prefabs` ziehen, Szenen-Objekt löschen
---
## 8. Boot-Szene
1. `File > New Scene` (Basic/URP-Template), `File > Save As``Assets/Scenes/Boot.unity`
2. `GameObject > Create Empty`, benennen `NetworkManager`
3. Component: `Network Manager`
4. Component: `Unity Transport` — im `Network Manager`-Inspector unter „Network Transport" zuweisen
5. `Player Prefab``Player`-Prefab aus Schritt 3 zuweisen
6. `Customer`-Prefab registrieren (siehe Kasten unten) — `ShelfSlot`, `CashRegister`, `StorageCrate` **nicht** hier eintragen, die kommen als Szenen-Objekte direkt in die Shop-Szene
7. `Don't Destroy On Load` angehakt lassen (Default) — muss den Szenenwechsel zu `Shop` überleben
8. Component: `NetworkBootstrap` (aus `AfterHours.Networking`), `Game Scene Name``Shop`
9. Canvas + Buttons für Host/Join (siehe unten)
### Customer im Network Prefabs registrieren
Das `Network Prefabs`-Feld im `NetworkManager` selbst nimmt nur Assets vom Typ
*Network Prefabs List* auf (z. B. `DefaultNetworkPrefabs`), keine einzelnen
Prefabs — deshalb taucht `Customer` dort nicht in einer Auswahl auf.
1. Im Project-Fenster die Datei `DefaultNetworkPrefabs` suchen (liegt meist
direkt unter `Assets/`, wird vom NetworkManager automatisch angelegt)
2. Einmal draufklicken — der Inspector zeigt jetzt den Inhalt *dieses* Assets
3. Dort gibt es eine eigene Liste „Network Prefabs" mit einem `+`-Button
4. `+` klicken → neuer Eintrag mit leerem Prefab-Feld
5. `Customer`-Prefab aus `Assets/Prefabs` in dieses Feld ziehen
Falls kein `DefaultNetworkPrefabs`-Asset existiert: Rechtsklick im
Project-Fenster → `Create > Netcode > Network Prefabs List` (Menüpfad kann
leicht abweichen), benennen, dann ins `NetworkManager`-Feld „Network Prefabs" ziehen.
Prüfen falls es trotzdem nicht klappt: hat das `Customer`-Prefab wirklich
eine `Network Object`-Component? (Prefab öffnen, Inspector prüfen.)
### Canvas mit Host/Join-Buttons
1. `GameObject > UI > Canvas` (legt automatisch ein `EventSystem`-Objekt mit an — nicht löschen)
2. Canvas auswählen, `GameObject > UI > Button` (ggf. Popup „Import TMP Essentials" bestätigen)
3. Umbenennen zu `HostButton`, im linken Bereich des Canvas positionieren
4. Beschriftung: Kind-Objekt `Text (TMP)` anklicken, Text-Feld auf „Host" ändern
5. Schritte 24 wiederholen für `JoinButton` mit Text „Join"
6. `HostButton` auswählen → Inspector → `Button (Script)` → Bereich „On Click ()"
7. `+` klicken → neuer Listeneintrag mit leerem Objektfeld
8. Das GameObject mit der `NetworkBootstrap`-Component reinziehen (das `NetworkManager`-Objekt aus Schritt 8.2)
9. Dropdown „No Function" → `NetworkBootstrap``HostGame ()` auswählen
10. Gleiches für `JoinButton`, aber `JoinGame ()`
---
## 9. Shop-Szene
1. `File > New Scene`, `File > Save As``Assets/Scenes/Shop.unity`
2. Grobes Blockout bauen (siehe unten)
3. `Floor` auswählen → `Add Component``Nav Mesh Surface` hinzufügen (Component aus `com.unity.ai.navigation` — ersetzt das alte, deprecated `Static > Navigation Static`-Flag)
4. Defaults meist ok (Agent Type: Humanoid, Collect Objects: All, Include Layers: Everything) — Wände blockieren dank ihrer Collider automatisch. Ganz unten in der Component auf `Bake` klicken (ohne das läuft kein `NavMeshAgent`)
5. Zwei leere GameObjects: `EntryPoint`, `ExitPoint`, in der Türlücke platziert
6. `GameObject > Create Empty``GameClock`, Components `GameClock` + `Network Object`
7. `GameObject > Create Empty``ShopEconomy`, Components `ShopEconomy` + `Network Object`
8. `GameObject > Create Empty``CustomerSpawner`, Components `CustomerSpawner` + `Network Object`
9. `GameObject > Create Empty``SupplierService`, Components `SupplierService` (aus `AfterHours.Economy`) + `Network Object`. `Catalog` → Asset, `Delivery Lead Hours` Default (4) — bei Standard-`GameClock`-Tempo (60 reale Sekunden = 1 Spielstunde) entspricht das 4 realen Minuten bis zur Lieferung, zum Testen ggf. runterdrehen
10. `ShelfSlot`-, `CashRegister`-, `StorageCrate`- und `OrderTerminal`-Prefabs aus dem Project-Fenster in die Szene ziehen und platzieren (23 Regale reichen fürs Erste)
11. `CustomerSpawner` verkabeln: `Customer Prefab` → Customer-Prefab, `Entry Point`/`Exit Point` → die beiden Transforms, `Register` → platzierte CashRegister-Instanz
12. **Wichtig:** `GameClock`, `ShopEconomy`, `CustomerSpawner`, `SupplierService`, `ShelfSlot`-, `CashRegister`-, `StorageCrate`- und `OrderTerminal`-Instanzen sind direkt in der Szene platziert ("in-scene placed NetworkObjects") — NGO spawnt sie automatisch, wenn der Server die Szene lädt. Keine Registrierung in der Network Prefabs List nötig (anders als beim `Customer`-Prefab).
### Grobes Blockout
**Boden:**
1. `GameObject > 3D Object > Plane`, benennen `Floor`
2. Position `(0, 0, 0)`. Standardgröße 10×10 Units (Meter) reicht fürs Erste; Scale anpassen für andere Größe (z. B. `1.5, 1, 1` für 15×10m)
**Wände:**
1. `GameObject > 3D Object > Cube`, benennen `Wall_North`
2. Transform: Position `(0, 1.5, 5)`, Scale `(10, 3, 0.2)`
3. 3× duplizieren (`Ctrl+D`), neu positionieren:
- `Wall_South`: Position `(0, 1.5, -5)`, Scale gleich
- `Wall_East`: Position `(5, 1.5, 0)`, Scale `(0.2, 3, 10)`
- `Wall_West`: Position `(-5, 1.5, 0)`, Scale `(0.2, 3, 10)`
4. Für einen Eingang: eine Wand (z. B. `Wall_South`) durch zwei kürzere Cubes ersetzen (Scale `(4, 3, 0.2)`) mit ca. 2m Lücke dazwischen als Tür
Cube-/Plane-Primitives bekommen automatisch einen passenden Collider — nichts extra nötig.
**Aufräumen (optional):** `GameObject > Create Empty``Blockout`, `Floor` + alle `Wall_*` per Drag & Drop als Kinder reinziehen.
Wände brauchen keine eigene `Nav Mesh Surface`/Modifier-Component — sie blockieren das NavMesh automatisch über ihre Collider, solange sie im „Include Layers"-Bereich der `Nav Mesh Surface` auf `Floor` liegen (Default: Everything). Farbe/Material ist rein kosmetisch, kann später kommen.
---
## 10. Build Settings
`File > Build Settings` (bzw. `Build Profiles` in Unity 6) → „Add Open Scenes" für beide Szenen, `Boot` an Index 0.
## 11. Testen
1. `Boot`-Szene öffnen, Play drücken
2. „Host" klicken → sollte automatisch in die `Shop`-Szene wechseln
3. Mit WASD/Maus bewegen
4. Regal anschauen, `E` am `StorageCrate` (Ware aufnehmen), dann am `ShelfSlot` (einräumen)
5. Warten, bis ein Kunde spawnt: läuft er zum Regal, nimmt Ware, stellt sich an? An der Kasse `E` zum Scannen/Kassieren
6. Am `OrderTerminal` `E` drücken → Guthaben (`ShopEconomy.Balance`, aktuell nirgends im UI sichtbar, ggf. Inspector der `ShopEconomy`-Instanz während Play beobachten) sollte sofort sinken. Nach `Delivery Lead Hours` Spielstunden sollte die Menge in der passenden `StorageCrate` steigen
Bei Problemen: genauer Fehler bzw. Console-Meldung notieren, dann gezielt nachschauen.