193 lines
8.4 KiB
Markdown
193 lines
8.4 KiB
Markdown
# Agrandissement de salles — Synchronisation multijoueur
|
|
|
|
## Ce que fait ce pack
|
|
|
|
Rend l'agrandissement de salle (clic [E] sur un panneau mural) **synchrone entre tous les joueurs** en multijoueur, tout en restant fonctionnel en solo.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Client joueur clique [E]
|
|
│
|
|
▼
|
|
PlayerInteraction.Ramasser()
|
|
│
|
|
▼
|
|
agr.DemanderAgrandir() ←─── [nouveau]
|
|
│
|
|
▼
|
|
SynchronisationAgrandissement.DemanderAgrandissement(salleId, direction)
|
|
│
|
|
├── Mode solo : execution directe locale
|
|
│
|
|
└── Mode multi :
|
|
│
|
|
▼
|
|
PlayerAgrandissementBridge.CmdDemanderAgrandissement (sur le joueur local)
|
|
│
|
|
▼
|
|
Serveur : SynchronisationAgrandissement.TraiterDemandeServeur
|
|
│
|
|
├── Valide (pas deja agrandi dans cette direction)
|
|
├── Ajoute a la SyncList des agrandissements effectues
|
|
│
|
|
▼
|
|
RpcLancerAgrandissement(salleId, direction)
|
|
│
|
|
▼
|
|
Chaque client + serveur : AgrandirLocal(false)
|
|
│
|
|
▼
|
|
Animation identique chez tous (meme parametres → meme geometrie)
|
|
```
|
|
|
|
## Script 1 — `SynchronisationAgrandissement.cs` (NOUVEAU)
|
|
|
|
Contient deux classes :
|
|
|
|
1. **`SynchronisationAgrandissement`** — singleton NetworkBehaviour, orchestre tout
|
|
2. **`PlayerAgrandissementBridge`** — NetworkBehaviour a ajouter au prefab du joueur pour porter la `[Command]`
|
|
|
|
## Script 2 — `AgrandissementSalle.cs` (MODIFIÉ)
|
|
|
|
Changements :
|
|
- Nouvelle méthode `DemanderAgrandir()` : point d'entrée multi
|
|
- Nouvelle méthode `AgrandirLocal(bool instantane)` : execute localement (avec ou sans anim)
|
|
- `Agrandir()` conservée pour compat : équivaut à `AgrandirLocal(false)`
|
|
- Toutes les coroutines d'animation (`ConstruireSol`, `ConstruireMurs`, `ConstruirePlafond`, `ConstruireEclairage`) acceptent un paramètre `skipVisuel` pour construire instantanément (rejeu client qui rejoint)
|
|
- Gardes `DedicatedServerMode.IsDedicatedServer` sur la création de `Material`/`TextMesh`/debris
|
|
- Layer `Emplacement` correctement appliqué aux emplacements de l'extension (il manquait dans l'original)
|
|
|
|
## Script 3 — `PlayerInteraction.cs` (MODIFIÉ)
|
|
|
|
Un seul changement : ligne ~933, `agr.Agrandir()` remplacé par `agr.DemanderAgrandir()`.
|
|
|
|
## Étapes dans Unity
|
|
|
|
### 1. Remplacer les 3 scripts
|
|
|
|
Copier dans `Assets/Scripts/` :
|
|
- `SynchronisationAgrandissement.cs` (nouveau fichier)
|
|
- `AgrandissementSalle.cs` (remplace l'existant)
|
|
- `PlayerInteraction.cs` (remplace l'existant)
|
|
|
|
### 2. Ajouter `SynchronisationAgrandissement` à la scène
|
|
|
|
Dans `Datacenter_01` :
|
|
1. Sélectionner le GameObject qui porte le `NetworkManager`
|
|
2. `Add Component` → `SynchronisationAgrandissement`
|
|
3. S'assurer que ce GameObject a un `NetworkIdentity` ; la plupart du temps le `NetworkManager` n'en a pas lui-même. Créer un enfant `SyncAgrandissement_Holder` avec un `NetworkIdentity` + le script si besoin.
|
|
|
|
**Important** : pour que Mirror synchronise le `SyncList`, ce GameObject doit être spawné sur le réseau. Deux options :
|
|
- **Option A (simple)** : le mettre dans `NetworkManager.spawnPrefabs` et le spawner au `OnStartServer` via un petit bootstrap
|
|
- **Option B (scène)** : garder le GameObject dans la scène. Mirror va automatiquement le traiter comme un objet de scène avec `NetworkIdentity`. Dans ce cas, s'assurer que l'objet porte **un `NetworkIdentity`** et qu'il est présent **dès l'ouverture de la scène**.
|
|
|
|
L'option B est ce que je recommande pour ton cas : Datacenter_01 est une scène fixe, tu ajoutes `SynchronisationAgrandissement` + `NetworkIdentity` sur un GameObject dédié, et Mirror le gère tout seul.
|
|
|
|
### 3. Ajouter `PlayerAgrandissementBridge` au prefab du joueur
|
|
|
|
1. Ouvrir le prefab du joueur (celui qui est dans `NetworkManager.playerPrefab`)
|
|
2. `Add Component` → `PlayerAgrandissementBridge`
|
|
3. Sauver le prefab
|
|
|
|
Sans ce composant sur le joueur, les clients ne pourront pas envoyer leur `CmdDemanderAgrandissement` vers le serveur.
|
|
|
|
### 4. Rebuild
|
|
|
|
- Client Windows (pour tester avec deux joueurs)
|
|
- Dedicated Server Linux (pour déployer sur la Debian)
|
|
|
|
## Test à faire
|
|
|
|
### Test 1 — Mode solo
|
|
1. Lancer en éditeur (play mode normal, pas host)
|
|
2. Cliquer [E] sur un panneau d'agrandissement
|
|
3. **Attendu** : l'animation se lance comme avant, salle agrandie à la fin
|
|
|
|
### Test 2 — Mode host + client
|
|
1. Lancer l'éditeur en Host
|
|
2. Lancer un build client et le connecter
|
|
3. **Host** clique [E] sur un panneau
|
|
4. **Attendu** : les deux voient la même animation en même temps, les nouveaux emplacements apparaissent des deux côtés
|
|
|
|
### Test 3 — Client déclencheur
|
|
1. Host + client
|
|
2. **Client** clique [E] sur un panneau
|
|
3. **Attendu** : les deux voient l'animation, la SyncList côté serveur contient l'entrée
|
|
|
|
### Test 4 — Dedicated + 2 clients
|
|
1. Lancer le dedicated sur la Debian
|
|
2. Connecter 2 clients Windows
|
|
3. Un des clients clique [E]
|
|
4. **Attendu** : les 2 clients voient l'animation synchrone, le serveur logue la création de l'extension
|
|
|
|
### Test 5 — Rejoin
|
|
1. Dedicated + 1 client
|
|
2. Le client déclenche l'agrandissement
|
|
3. Un **2e client** se connecte APRÈS
|
|
4. **Attendu** : le 2e client voit l'extension instantanément (pas d'animation), l'état est cohérent
|
|
|
|
## Points d'attention
|
|
|
|
### GameEconomy
|
|
Ton `GameEconomy` est en mode sandbox, donc les `TenterAchat` passent toujours. La validation économique serveur n'est pas implémentée dans ce pack, elle le sera quand tu sortiras du sandbox.
|
|
|
|
### Emplacements de baies
|
|
Les `EmplacementBaie` de l'extension sont créés **localement sur chaque instance** (pas via `NetworkServer.Spawn`). C'est cohérent avec le pattern actuel de `SalleDatacenter.GenererEmplacementsBaies()` qui fonctionne déjà en multi.
|
|
|
|
Les baies qui seront placées dessus continueront d'utiliser le flux `CmdPlacerBaie` qui spawne bien via `NetworkServer.Spawn` dans `BoutiqueReseau.TraiterPlacementBaieServeur`.
|
|
|
|
### Colliders sol + murs
|
|
Ils sont créés **partout (serveur et clients)** car ils sont nécessaires pour :
|
|
- Le CharacterController du joueur (marcher dans la nouvelle zone)
|
|
- La physique des objets posés
|
|
- Les raycasts d'interaction
|
|
|
|
Pas de risque de "tomber dans le vide" côté serveur.
|
|
|
|
### Néons
|
|
Sur le dedicated server, les `Light` ne sont pas créées (gain CPU + logs plus propres). Les clients les créent normalement. C'est sans impact gameplay.
|
|
|
|
## Workflow de debug
|
|
|
|
Côté serveur dedicated, les logs à surveiller :
|
|
|
|
```
|
|
[SyncAgrandissement] Agrandissement valide : 1_Nord (total : 1)
|
|
```
|
|
|
|
Côté client :
|
|
```
|
|
[SyncAgrandissement] Rpc recu, execution agrandissement : salle 1 direction Nord
|
|
AgrandissementSalle: PHASE 3 - Début construction sol
|
|
AgrandissementSalle: PHASE 7 - Construction complète !
|
|
```
|
|
|
|
Si tu vois :
|
|
```
|
|
[SyncAgrandissement] Mur introuvable : salle 1 direction Nord
|
|
```
|
|
|
|
Ça veut dire que le `salleId` ou la direction ne correspondent à aucun mur dans la scène. Vérifier que `SalleDatacenter.salleId` est bien = 1 (ou que le fallback "n'importe quel mur dans la bonne direction" trouve un match).
|
|
|
|
Si tu vois :
|
|
```
|
|
[PlayerAgrandissementBridge] Instance SynchronisationAgrandissement introuvable cote serveur !
|
|
```
|
|
|
|
Ça veut dire que le GameObject qui porte `SynchronisationAgrandissement` n'a pas bien été spawné côté serveur. Vérifier qu'il est présent dans la scène **au démarrage** (option B) ou dans `NetworkManager.spawnPrefabs` + spawné au `OnStartServer` (option A).
|
|
|
|
## Bugs connus limités
|
|
|
|
1. **Chat spam si plusieurs clients déclenchent en même temps** : si 2 clients cliquent [E] sur le même panneau dans la même frame, le serveur validera le premier et rejettera le second (log warning "deja agrandi"). Pas grave pour les joueurs.
|
|
|
|
2. **Anim qui démarre décalée** : la latence réseau entre Cmd et Rpc peut faire que les clients voient l'animation avec ~50-200ms de retard entre eux. Acceptable en coop standard.
|
|
|
|
3. **Animation coupée si un client disconnect pendant l'anim** : comme c'est local sur chaque client, ça ne casse rien pour les autres. Le joueur qui reconnect verra l'extension déjà construite via le rejeu.
|
|
|
|
## À implémenter plus tard (pas dans ce pack)
|
|
|
|
- Validation économique serveur-side (quand tu sortiras du sandbox)
|
|
- Persistence des agrandissements dans le SaveManager
|
|
- Support multi-salles pour l'agrandissement (actuellement `SynchronisationAgrandissement` trouve `FindObjectOfType<SalleDatacenter>()`, donc ça ciblera toujours la salle 1 ; à affiner quand tu auras plusieurs salles agrandissables)
|