6.7 KiB
6.7 KiB
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 :
- La classe passe de
MonoBehaviouràNetworkBehaviour - Ajout d'une
SyncList<string>qui contient les créations de salles (ex:"1_Ouest","2_Nord") - Ajout d'un
[ClientRpc] RpcLancerConstructionSallequi broadcast l'ordre aux clients CreerNouvelleSallecôté serveur :- Enregistre dans la SyncList (pour rejoin)
- Broadcast le Rpc aux clients
- Chaque instance (serveur + clients) exécute l'animation localement via
AnimationCreationSalleLocal - 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) - Le code de génération est refactorisé : la partie "construire la géométrie de la salle + couloir" est extraite dans
CreerSalleGeometriepour être réutilisée par le flux normal ET le rejoin - Gardes
DedicatedServerMode.IsDedicatedServerajouté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
- Dans la scène
Datacenter_01, trouver le GameObject qui porte le composantGestionnaireMultiSalles - 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)
- 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
.cscorrespondants (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
- Remplacer
Assets/Scripts/GestionnaireMultiSalles.cspar la nouvelle version - Vérifier / ajouter
NetworkIdentitysur le GameObject qui porte ce composant - Sauver la scène
- Build client Windows (pour pouvoir tester)
- Build Dedicated Server Linux et déployer sur la Debian
Test à faire
Test 1 — Solo (éditeur Play)
- Lancer l'éditeur en Play (pas host)
- Aller au Terminal, acheter "Nouvelle salle Ouest"
- Attendu : le mur explose, couloir apparaît, salle Ouest se construit comme avant
Test 2 — Host + Client
- Éditeur en Host, un build Windows connecté en client
- Le host achète "Nouvelle salle Est"
- Attendu : les DEUX voient la même animation + couloir + salle créée
Test 3 — Client déclencheur
- Host + Client
- Le client achète "Nouvelle salle Nord"
- Attendu : les DEUX voient la même animation
Test 4 — Dedicated + 2 clients
- Dedicated sur Debian + 2 clients Windows
- Un client achète "Nouvelle salle Sud"
- Attendu : les 2 clients voient l'animation synchrone, le serveur logue la création
Test 5 — Rejoin
- Dedicated + 1 client
- Le client achète "Nouvelle salle Ouest"
- Un 2e client se connecte APRÈS
- 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
GestionnaireMultiSallesa bien unNetworkIdentity - 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.TraiterPlacementBaieServeurqui utilise bienNetworkServer.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