In this lesson, you will learn how to ensure that players who connect to an ongoing match instantly receive the accurate, current state of the game world.
When a new client joins an active session, they start with a "blank slate." They haven’t seen the events, score changes, or object spawns that occurred while the match was already in progress. To prevent a "desync" where the new player sees a different reality than the rest of the lobby, we rely on the NetworkVariable synchronization mechanism.
The Mechanism of Late Joining
In Netcode for GameObjects, the NetworkManager automatically handles the synchronization of NetworkVariable values when a new client connects. When a NetworkObject is spawned, the server sends the current values of all its NetworkVariable components to the new client during the connection handshake. The client’s local instance of that object then initializes its state to match the server’s authoritative data.
Ensuring Correct Initialization
The challenge arises if you attempt to access these variables inside Start() or Awake(). Because the network data may not have arrived yet, those variables might hold their default values rather than the synced values. To handle late joiners correctly, you must rely on the OnValueChanged callback.
public class GameStateController : NetworkBehaviour
{
public NetworkVariable<int> currentScore = new NetworkVariable<int>(0);
public override void OnNetworkSpawn()
{
// Use the current value immediately upon spawning
UpdateUI(currentScore.Value);
// Register the callback to handle future updates
currentScore.OnValueChanged += (oldVal, newVal) => UpdateUI(newVal);
}
}
By placing your initialization logic inside OnNetworkSpawn(), you ensure that the code executes only after the object is fully initialized and synchronized with the server's state. If you rely on Start(), your UI might briefly show "0" before the actual score arrives, creating a jarring experience for the user. Always use OnNetworkSpawn to perform "state-aware" initialization for late-joining players.
Key Takeaway: Always utilize OnNetworkSpawn to initialize your game logic, as it guarantees that your NetworkVariables have been populated with the server’s current authoritative data before your scripts attempt to access them.