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>
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
# 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 2–4 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 (2–3 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.
|
||||
Reference in New Issue
Block a user