I’m currently working on a network project and I did not found a simple way to set variable on spawned gameobject on clients.
If I do something like this :
GameObject go = Instantiate(prefab);
go.GetComponent<AnyComponent>().anyVariable = anyValue;
NetworkServer.Spawn(go);
The anyVariable will be set only on host.
I know about
, and it work on some situations, for exemple if it always spawn with the same values to change (you cannot add custom parameters), or for pooling, and you have to parse all assetId each time. But it does not help if you want dynamic values.
Anyone know a way to pass a changing parameter on spawn that will be also changed in all client? for exemple if Server decided to spawn an enemy prefab wich have 5 attackPoints, but sometime spawn it with 10 or 20 (not for players, for any kind of object)?
I know syncvar are not sent on network for initial state, only when value change on server, or on spawn.
Do you know a way to share initial syncvar values?
And again : set a variable only existing for initial setup (like max life, color) to syncvar , even if it does not change during gameplay, and change it during the spawning command is the only way to set initial values on client after spawning?
I’m not sure I completely follow, but I’ll tell you what I know.
The client will call…
Client NetworkBehaviour.Awake() //the syncVar is not updated yet
Client NetworkBehaviour.OnStartClient() //the syncVar now has the proper value EDIT Use OnStartClient() not Start()
But the SyncVar does not call the hook during initialization regardless if the value has changed. You must manually call the hook if you want something to happen.
So the order might look something like this
Server.Awake() //set SyncVar value here
SpawnObject()
Server.Start()
Client.Awake()
Client.OnStartClient() //on the client use the SyncVar value here… because it is guaranteed to be updated.
So to recap there are 2 rules:
1: On the server set SyncVar values BEFORE calling spawn()
2: On the client only use SyncVar values AFTER OnStartClient() has been called (not during Awake because they will not be updated yet)
Ok thank you, usefull to know for initialisation. I’m still a bit confused to use SyncVar for init values only that will not change during the game, but if it works why not.
But if things happen in this order:
server call spawn()
server change syncvar values during gameplay
later during the game a new client connect : the spawned objects seems to not have the correct syncvar values (after start) until the values are modified again on server.
What do you mean by call Hook manually? on client or server? on client it would be impossible since the hook have the right value need in parameter, and on server how to send the current values again? re affectation on the same value? and how to detect on server a new client instance has been spawned on a new client? (as Command cannot be call on client whitout authority)?
For SyncVar’s that are init values that never change
You can use SyncVar’s but use NetworkSettingsAttribute.sendInterval = 99999999 (~inf) to prevent any future updates or bandwidth. Unfortunately the sendInterval is common to the entire NetworkBehaviour so you cannot mix send intervals of 0.1s (the default) with send intervals of 99999999 (~inf) without having 2 separate NetworkBehaviour scripts.
“- later during the game a new client connect : the spawned objects seems to not have the correct syncvar values (after start) until the values are modified again on server.” This seems bugged. The client should always have the latest values by the time Start() is called on the client. Note that even though the value may have changed the SYNCVAR HOOK WILL NOT BE CALLED DURING INITIALIZATION! So during client OnStartClient() you must manually check to see if the SyncVar value has changed (or manually call the SyncVar hook on the client)
***EDIT: SyncVars will have correct values after OnStartClient() not Start()
“The values of SyncVars on object are guaranteed to be initialized correctly with the latest state from the server when this function is called on the client”
Ok, but how do you do that on a object on client that does not have authority? You cannot call command. And I don’t want to set a syncVar but to “ask server to send me the last value” of the syncVar.
Any kind of object, player, enemies, managers. anything that have a networkidentity and is on client.
I need to have any value correctly initialized when joining a existing party (where values on server may have changed). Seems that client have to wait server object change the sync value again, or to send a raw message to ask for this values.