8.4 KiB
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 :
SynchronisationAgrandissement— singleton NetworkBehaviour, orchestre toutPlayerAgrandissementBridge— 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ètreskipVisuelpour construire instantanément (rejeu client qui rejoint) - Gardes
DedicatedServerMode.IsDedicatedServersur la création deMaterial/TextMesh/debris - Layer
Emplacementcorrectement 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 :
- Sélectionner le GameObject qui porte le
NetworkManager Add Component→SynchronisationAgrandissement- S'assurer que ce GameObject a un
NetworkIdentity; la plupart du temps leNetworkManagern'en a pas lui-même. Créer un enfantSyncAgrandissement_Holderavec unNetworkIdentity+ 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.spawnPrefabset le spawner auOnStartServervia 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 unNetworkIdentityet 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
- Ouvrir le prefab du joueur (celui qui est dans
NetworkManager.playerPrefab) Add Component→PlayerAgrandissementBridge- 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
- Lancer en éditeur (play mode normal, pas host)
- Cliquer [E] sur un panneau d'agrandissement
- Attendu : l'animation se lance comme avant, salle agrandie à la fin
Test 2 — Mode host + client
- Lancer l'éditeur en Host
- Lancer un build client et le connecter
- Host clique [E] sur un panneau
- 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
- Host + client
- Client clique [E] sur un panneau
- Attendu : les deux voient l'animation, la SyncList côté serveur contient l'entrée
Test 4 — Dedicated + 2 clients
- Lancer le dedicated sur la Debian
- Connecter 2 clients Windows
- Un des clients clique [E]
- Attendu : les 2 clients voient l'animation synchrone, le serveur logue la création de l'extension
Test 5 — Rejoin
- Dedicated + 1 client
- Le client déclenche l'agrandissement
- Un 2e client se connecte APRÈS
- 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
-
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.
-
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.
-
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
SynchronisationAgrandissementtrouveFindObjectOfType<SalleDatacenter>(), donc ça ciblera toujours la salle 1 ; à affiner quand tu auras plusieurs salles agrandissables)