#NetworkVariable w/ RPCs
1 messages · Page 1 of 1 (latest)
That last block has a couple issues
- Multiple clients are setting the value of the NetworkVariable. Which is not supposed to be done. The idea is that one person (the owner) sets the value and it gets auto synced to everyone.
- You're sending attributes.Value through an RPC which doesn't make sense. If you set attributes.Value (from the owner), that means it got synced to all other connections and there's no point in using an RPC.
Oh interesting I must have made some other mistake before since it tdidnt work without the RPC. Probably the first thing.
attributes.Value.Health = HPI'm not sure this works or is how you're supposed to set NetworkVariables structs or classes. I think you have to send the whole Class, even if you are just changing one variable of the class.
NetworkVariables are a way of synchronizing properties between servers and clients in a persistent manner, unlike RPCs and custom messages, which are one-off, point-in-time communications that aren't shared with any clients not connected at the time of sending. NetworkVariables are session-mode agnostic and can be used with either a client-serve...
I would take a step back and review this bit of sample. You'll see the simplicity of working with NetworkVariable.
The server owns the door, so they're the only one who is to set the NetworkVariable.
If a client wishes to open the door (and thus set the NetworkVariable) they send a [Rpc(SendTo.Server)] to the server to set it for them.
and then that change of the NetworkVariable's value is automatically synced to all clients.
I'm not sure sure what you mean with how you're supposed to set it. I think I get the server thing was just trying to fix stuff before and did it wrong.
You're seeing your NetworkVariable flicker because people who don't have permission to write to it are overwriting the value that is getting synced to them.
By default, NetworkVariables are owned by the server. So only the server can set them.
That makes sense, I just mean how you said " I think you have to send the whole Class, even if you are just changing one variable of the class."
This is just a guess. It may actually work. But until you fix the other issues it'll be hard to tell.
If your attributes network variable will automatically sync to the clients. So no need for client RPCs
So is it mostly a case of putting all the variable changes inside a if(IsServer)?
If it's being changed in a server RPC, that's not needed either. It will never run a client
Also network variables don't work with classes. They should be structs
When it's in IsServer or set to send only to server it works for the host but only the host, clients don't seem to sync.
How are you checking the value?
on the clients
I have a test HUD element that is just text that gets a reference to all the NetworkedGameStats components and grabs the values from that
Code?
foreach(GameObject player in playerObjs) { if (player != null) { NetworkedGameStats stats = player.GetComponent<NetworkedGameStats>(); GameplayUI.transform.GetChild(2).GetComponent<TextMeshProUGUI>().text += stats.GetName() + " - Health: " + stats.GetHP() + "\n"; } }
public int GetHP() { return attributes.Value.Health; }
That looks fine. Although I would encourage you to use OnValueChange.
How are you setting the NetworkVariable now?
Is this getting called in Update()?
`[Rpc(SendTo.ClientsAndHost)]
public void DamageRPC(int damage)
{
if(IsServer)
{
int HP = attributes.Value.Health;
HP = HP - damage;
attributes.Value.Health = HP;
}
if(IsLocalPlayer)
{
UpdateHUDDisplay();
}
}`
Yes, just for testing reasons though
UpdateHUDDisplay won't do anything here. If you're calling the other thing in Update, you should be seeing the values get synced.
That's for the local non-test HUD, the string one I am calling on update is not syncing.
Then that would lead me to believe that what I said before is true. attributes.Value.Health = HP; this does not trigger a sync.
I would say you should probably set attributes.Value only
Which means creating a new Attributes, setting the Health and then setting that to the Value.
I think that works now, even updates the other variables that I didn't update to use this yet
Here is what I did
if(IsServer) { AttributeContainer new_attributes = new AttributeContainer(attributes.Value); int HP = new_attributes.Health; HP = HP - damage; new_attributes.Health = HP; attributes.Value = new_attributes; }