TOOLBOX / TUTORIAL

MirrorLobbyKit: 4-Scene Lobby → Gameplay Template

A step-by-step guide to wiring up a Mirror-powered multiplayer shell: Splash → Main Menu → Lobby → Gameplay.

📜 Get the Script: Mirror-Lobby-Kit on GitHub

 

📂 Prerequisites & Folder Layout

Organize your project:


/Assets/
  /Scripts/
    StartupUIManager.cs
    CustomNetworkManager.cs
    NetworkPlayer.cs
    PlayerLobbyUIEntry.cs
    GameplayPlayer.cs
    GameplayPlayerUIEntry.cs
    GameplayUIManager.cs
  /Prefabs/
    NetworkPlayer.prefab
    PlayerLobbyUIEntry.prefab
    GameplayPlayer.prefab
    GameplayPlayerUIEntry.prefab
  /Scenes/
    Splash.unity
    MainMenu.unity
    Lobby.unity
    Gameplay.unity
    

1️⃣ Startup & Main Menu (StartupUIManager.cs)

  • 🎯 Purpose: Collect IP, port & player name → Start Host/Client.
  • 🔧 Inspector: addressField, portField, userName, hostButton, joinButton.
  • 🚀 Host:
    
    SetPlayerName();
    ApplyNetworkPort();
    NetworkManager.singleton.StartHost();
            
  • 🚪 Join:
    
    SetPlayerName();
    ApplyNetworkPort();
    NetworkManager.singleton.networkAddress = addressField.text;
    NetworkManager.singleton.StartClient();
            

Wire up: Add three TMP InputFields + two Buttons to your Canvas and assign them in the Inspector.


2️⃣ Network Flow & Scene Management (CustomNetworkManager.cs)

  • 🎯 Purpose: Persistent lobby player → swap in-game avatars on scene change.
  • 🔍 Awake: Caches short names for `onlineScene` (Lobby) & `gameplayScenePath` (Gameplay).
  • 🖥️ OnStartHost: Mirror auto-loads Lobby.
  • 🔌 OnClientConnect: Sends `Ready()` + `AddPlayer()`.
  • OnServerAddPlayer: Instantiates your `networkPlayerPrefab`.
  • 🔄 OnServerSceneChanged:
    • 🏠 Lobby: Respawns missing `NetworkPlayer` when returning.
    • 🎮 Gameplay: `NetworkServer.Spawn(gameplayPlayerPrefab, conn)` for each player.
  • ▶️ StartGameplayScene() & ReturnToLobbyScene(): server-only scene switches.

Wire up: In Splash scene, add `CustomNetworkManager`, assign your scenes + prefabs in the Inspector.


3️⃣ Persistent Player Data (NetworkPlayer.cs)

  • 🎯 Purpose: Sync name, ready/host flags, ping; spawn lobby UI rows.
  • 🔗 SyncVars: `playerName`, `isReady`, `isHost`, `pingMs` (with hooks).
  • 🚀 OnStartLocalPlayer: `CmdInitProfile(...)` sets initial name & host flag.
  • ⏱️ Update(): Every second measures `NetworkTime.rtt` → `CmdReportPing()` to sync `pingMs`.
  • 📋 Scene-watch: On lobby load → spawn/destroy a UI row via coroutine.
  • 📜 Commands: CmdToggleReady(), CmdStartGame(), CmdReturnToLobby().

Wire up: Create `NetworkPlayer.prefab` with a `NetworkIdentity` + this script; assign `lobbyRowPrefab`.


4️⃣ Lobby UI Row (PlayerLobbyUIEntry.cs)

  • 🎯 Purpose: One row in your Lobby list showing name, ✔ tick, host icon & a button.
  • 🔗 Bind(NetworkPlayer): Wires the row, sets name, icon color.
  • 🔄 Refresh(): Called on SyncVar hooks to update visuals.
  • 🔘 Buttons: - **Start** if you’re host → `CmdStartGame()` - **Ready** if you’re client → `CmdToggleReady()`

Wire up: Build a prefab with `TMP_Text`, `Image`, `Button`, attach this script, then assign it in `NetworkPlayer`.


5️⃣ Gameplay UI & Rows

a) GameplayPlayer (GameplayPlayer.cs)

A minimal network avatar in the Gameplay scene with just a synced `playerName`.

b) GameplayPlayerUIEntry (GameplayPlayerUIEntry.cs)

  • 🎯 Bind(NetworkPlayer): Sets player name on the row.
  • 🎨 UpdatePingDisplay(int): Recolors a ping icon based on `pingMs`.
  • Fallback: Can use `NetworkTime.rtt` in `Update()` for quick tests.

c) GameplayUIManager (GameplayUIManager.cs)

  • 🔍 Start(): Waits for the local player → calls `Init()`.
  • 🚪 Init(): Shows **Back to Lobby** for host + wires it to `CmdReturnToLobby()`.
  • 📋 BuildPlayerList(): Instantiates a row for each `NetworkPlayer` found in scene.
  • 📡 UpdatePingFor(NetworkPlayer): Static hook updates a single row’s ping icon when `pingMs` changes.

Wire up: In your Gameplay Canvas assign `backToLobbyBtn`, `playerListParent`, and `playerEntryPrefab`.


🚀 Running & Extending

  1. 🔨 Build & Run two instances:
    • Host: Main Menu → Start Host → see yourself in Lobby
    • Client: Enter IP + port → Join → appear in Lobby
  2. ✅ Client “Ready” + Host “Start” → everyone loads Gameplay
  3. 🔙 “Back to Lobby” returns all players cleanly

💡 Pro Tips & Next Steps

  • 🔑 Add a lobby password in `StartupUIManager`
  • 📜 Document everything in a README.md for GitHub & itch.io
  • 🎨 Polish UI: consistent fonts, colors, animations
  • 🌐 Test Internet play: router port-forwarding & firewall
  • ⚔️ Next Project: drop this shell into your roguelike to handle networking