148 lines
6.7 KiB
Markdown
148 lines
6.7 KiB
Markdown
# Sync multi des nouvelles salles (GestionnaireMultiSalles v2.0)
|
|
|
|
## Contexte
|
|
|
|
Ton dernier test a révélé que j'avais synchronisé le mauvais système :
|
|
- Tu utilises **`GestionnaireMultiSalles`** (achat "Nouvelle salle Ouest/Est/Nord/Sud" au Terminal)
|
|
- J'avais synchronisé **`AgrandissementSalle`** (panneau mural, qui n'est plus utilisé)
|
|
|
|
Ce pack corrige ça.
|
|
|
|
## Ce qui change
|
|
|
|
Un seul fichier patché : **`GestionnaireMultiSalles.cs` v2.0**
|
|
|
|
Changements :
|
|
1. La classe passe de `MonoBehaviour` à **`NetworkBehaviour`**
|
|
2. Ajout d'une **`SyncList<string>`** qui contient les créations de salles (ex: `"1_Ouest"`, `"2_Nord"`)
|
|
3. Ajout d'un **`[ClientRpc] RpcLancerConstructionSalle`** qui broadcast l'ordre aux clients
|
|
4. `CreerNouvelleSalle` côté serveur :
|
|
- Enregistre dans la SyncList (pour rejoin)
|
|
- Broadcast le Rpc aux clients
|
|
5. Chaque instance (serveur + clients) exécute l'animation **localement** via `AnimationCreationSalleLocal`
|
|
6. Nouvelle méthode `OnStartClient` : les clients qui rejoignent en cours de partie relisent la SyncList et rejouent toutes les salles en mode **instantané** (pas d'animation)
|
|
7. Le code de génération est refactorisé : la partie "construire la géométrie de la salle + couloir" est extraite dans `CreerSalleGeometrie` pour être réutilisée par le flux normal ET le rejoin
|
|
8. Gardes `DedicatedServerMode.IsDedicatedServer` ajoutées partout où du Material/Light est créé (pas de shaders côté serveur)
|
|
|
|
## Setup Inspector
|
|
|
|
**Important** : `GestionnaireMultiSalles` est maintenant un `NetworkBehaviour`, donc il a besoin d'un `NetworkIdentity` sur son GameObject.
|
|
|
|
### Étapes
|
|
|
|
1. Dans la scène `Datacenter_01`, trouver le GameObject qui porte le composant `GestionnaireMultiSalles`
|
|
2. Si ce GameObject n'a **pas** de `NetworkIdentity` :
|
|
- `Add Component` → `NetworkIdentity`
|
|
- Dans l'Inspector du `NetworkIdentity`, **ne coche rien** (ni "Server Only" ni "Local Player Authority" — c'est un objet serveur autoritaire qui synchronise via la SyncList)
|
|
3. Sauver la scène (`Ctrl+S`)
|
|
|
|
### Note sur les autres composants
|
|
|
|
Tu peux **retirer** maintenant :
|
|
- `SynchronisationAgrandissement` (de la scène)
|
|
- `PlayerAgrandissementBridge` (du prefab joueur)
|
|
- Les 2 fichiers `.cs` correspondants (si tu veux nettoyer)
|
|
|
|
Puisque `AgrandissementSalle` n'est plus utilisé dans ta version actuelle, les 2 scripts que j'avais livrés hier ne servent plus à rien. Tu peux les garder dans le code mort s'il te semble possible d'y revenir plus tard.
|
|
|
|
## Actions à faire
|
|
|
|
1. **Remplacer** `Assets/Scripts/GestionnaireMultiSalles.cs` par la nouvelle version
|
|
2. **Vérifier / ajouter** `NetworkIdentity` sur le GameObject qui porte ce composant
|
|
3. **Sauver la scène**
|
|
4. **Build client Windows** (pour pouvoir tester)
|
|
5. **Build Dedicated Server Linux** et déployer sur la Debian
|
|
|
|
## Test à faire
|
|
|
|
### Test 1 — Solo (éditeur Play)
|
|
1. Lancer l'éditeur en Play (pas host)
|
|
2. Aller au Terminal, acheter "Nouvelle salle Ouest"
|
|
3. **Attendu** : le mur explose, couloir apparaît, salle Ouest se construit comme avant
|
|
|
|
### Test 2 — Host + Client
|
|
1. Éditeur en Host, un build Windows connecté en client
|
|
2. Le **host** achète "Nouvelle salle Est"
|
|
3. **Attendu** : les DEUX voient la même animation + couloir + salle créée
|
|
|
|
### Test 3 — Client déclencheur
|
|
1. Host + Client
|
|
2. Le **client** achète "Nouvelle salle Nord"
|
|
3. **Attendu** : les DEUX voient la même animation
|
|
|
|
### Test 4 — Dedicated + 2 clients
|
|
1. Dedicated sur Debian + 2 clients Windows
|
|
2. Un client achète "Nouvelle salle Sud"
|
|
3. **Attendu** : les 2 clients voient l'animation synchrone, le serveur logue la création
|
|
|
|
### Test 5 — Rejoin
|
|
1. Dedicated + 1 client
|
|
2. Le client achète "Nouvelle salle Ouest"
|
|
3. Un **2e client** se connecte APRÈS
|
|
4. **Attendu** : le 2e client voit la nouvelle salle + le couloir déjà construits (rejeu instantané, pas d'anim)
|
|
|
|
## Diagnostic
|
|
|
|
Dans les logs, tu devrais voir :
|
|
|
|
**Côté serveur** :
|
|
```
|
|
[MultiSalles] Salle enregistree dans SyncList : 1_Ouest (total : 1)
|
|
[MultiSalles] Debut construction locale salle Ouest depuis Salle 1 (instantane=False)
|
|
[MultiSalles] Mur DC_MurEst percé avec morceaux latéraux
|
|
[MultiSalles] Nouvelle salle creee localement : Salle 2 (15x10m) direction Ouest
|
|
```
|
|
|
|
**Côté client** :
|
|
```
|
|
[MultiSalles] Rpc recu : construction salle Ouest depuis parent id=1
|
|
[MultiSalles] Debut construction locale salle Ouest depuis Salle 1 (instantane=False)
|
|
[MultiSalles] Mur DC_MurEst percé avec morceaux latéraux
|
|
[MultiSalles] Nouvelle salle creee localement : Salle 2 (15x10m) direction Ouest
|
|
```
|
|
|
|
**Si rien ne se passe côté client** malgré le Rpc envoyé :
|
|
- Vérifier que le GameObject qui porte `GestionnaireMultiSalles` a bien un `NetworkIdentity`
|
|
- Vérifier dans Mirror Inspector que le NetworkBehaviour est bien enregistré
|
|
|
|
**Si "Salle parente id=X introuvable localement, skip"** :
|
|
- Problème de timing : le client n'a pas encore sa salle 1 enregistrée
|
|
- Pas grave dans 99% des cas (la salle 1 s'enregistre au démarrage via `SalleDatacenter.Start()`), mais si ça arrive à un client qui rejoint tardivement, le rejeu va skipper proprement
|
|
|
|
## Ce qui n'est PAS encore synchronisé
|
|
|
|
- **Les équipements placés dans les nouvelles salles** : quand un joueur pose une baie dans la salle 2, ça passe par `BoutiqueReseau.TraiterPlacementBaieServeur` qui utilise bien `NetworkServer.Spawn`, donc **c'est déjà synchronisé**. Pas de travail.
|
|
- **L'état "mur percé" dans la SyncList** : je ne track pas séparément les percements de mur, je track la création de salle. Le percement est fait automatiquement quand la salle est créée (dans `AnimationCreationSalleLocal`). Donc pas de divergence possible.
|
|
- **L'ordre des salles créées** : la SyncList conserve l'ordre d'insertion. Si un client rejoint, il rejoue dans l'ordre → pas de conflit.
|
|
|
|
## Architecture en un schéma
|
|
|
|
```
|
|
Client achete "Nouvelle salle Ouest" au Terminal
|
|
│
|
|
▼
|
|
BoutiqueReseau.DemanderCommandeSalle
|
|
│
|
|
▼
|
|
PlayerBoutiqueCommande.CmdCommanderSalle (deja en place, aucun changement)
|
|
│
|
|
▼
|
|
[SERVEUR] BoutiqueReseau.TraiterCommandeSalleServeur
|
|
│
|
|
▼
|
|
[SERVEUR] GestionnaireMultiSalles.CreerNouvelleSalle
|
|
│
|
|
├── Ajoute "1_Ouest" a _sallesSyncList (→ sync auto aux clients)
|
|
│
|
|
└── RpcLancerConstructionSalle(1, "Ouest")
|
|
│
|
|
├── [CLIENT 1] StartCoroutine(AnimationCreationSalleLocal(1, "Ouest", false))
|
|
├── [CLIENT 2] StartCoroutine(AnimationCreationSalleLocal(1, "Ouest", false))
|
|
└── [HOST si applicable] skip (deja joue cote serveur)
|
|
|
|
[NOUVEAU CLIENT qui rejoint plus tard]
|
|
│
|
|
▼
|
|
OnStartClient : lit _sallesSyncList → rejoue chaque entree en mode instantane=true
|
|
```
|