I have a problem with synchronizing network variables when using Distributed Authority mode. My code is pretty simple:
Each player that joins spawns his PlayerObject
PlayerObject has one NetworkVariable
PlayerObject ownership is set to None - as per documentation
The problem is that when SessionOwner (host) spawns his PlayerObject first (as he loads his scene first), the client who joins later will not have host’s PlayerObject network variable synced correctly.
However, host will have client’s PlayerObject NetworkVariable synced correctly. Also, when I wait for all players to be fully connected before spawning any PlayerObject, everything works as intended.
Method to spawn Local Player - Called on every client after he is connected:
private void SpawnPlayer()
{
var player = Instantiate(humanPlayerPrefab);
player.NetworkObject.SpawnAsPlayerObject(NetworkManager.LocalClientId, destroyWithScene: true);
}
Network variable initialization in Player.cs script:
Initial value is set correctly - to 15 minutes, but OnValueChanged never triggers on late joining client - for Host’s owned PlayerObject. The NetworkVariable itself is not synchronized at all.
If anyone is interested on how I update the timeLeft value:
When are you spawning the session owner’s player?
Using the Distributed authority general quick start ConnectionManager as a reference, are you spawning the player prefabs right after MultiplayerService.Instance.CreateOrJoinSessionAsync or are you waiting for the NetworkManager.OnClientConnectedCallback to be invoked?
If it’s a problem that it will fire once instantly, you can set the timer value once to prevent that.
Time left can be calculated by subtracting Time.time.
Note that time may progress slower that way if you reset it every second because Update may do the reset at 1.016 seconds and that also accumulates. Perhaps even better is to cast time to int and record whenever that changes:
I’m waiting for NetworkManager.OnClientConnectedCallback to be invoked on LocalClient before spawning local PlayerObject. As I said this works as intended if I wait for everyone to connect before spawning any PlayerObjects, but it doesn’t work when I don’t.
Its called on every LocalClient after he is fully connected. Basically right after NetworkManager.OnClientConnectedCallback is invoked, as per documentation.
I probably didn’t explain this in a good way, what I meant is that for the Host, other client’s PlayerObject NetworkVariables are synchronized correctly no matter what but its not working in reverse - Host’s NetworkVariables are not synchronized on other client. Basically the one who joins first will have everything working fine.
Yes its true because the timer is updating for Host but not for other client so the code is running on Host’s (Authority) machine.