I am trying to understand some concepts in Unity.
I am spawning objects on the Host using :
GameObject player = Instantiate(playerPrefab, vector3, Quaternion.identity);
player.GetComponent<PlayerUiLoader>().LoadPlayer("Player 1");
player.GetComponent<NetworkObject>().Spawn();
The PlayerUiLoader
is only here to display the name of the player
above his head, and the script is nested on the playerPrefab
.
Now, when i LoadPlayer
, the clients don't see the name, but they see the spawned player.
Why the player
spawned has not inherited his attributes / script before spawning ?
What is the right way to do in these circumstances ?
Note : the player
prefab here has a clientNetworkTransform
and is transformed over the network, but the Network Transform
script makes no changes, unfortunately (it was the first I have tried).
Edit : This is the LoadPlayer
method, which is working fine on the Host for any player spawned :
public void LoadPlayer(string name)
{
username.text = name;
}
Is the ClientRpc
method the only one that can work in such situation ?
Why the Network Object spawned doesn't inherit from the previously set attributes ?
To make sure the player name is visible to all clients, you would need to synchronize the player's UI information across the network.
That can be achieved using a
ClientRpc
method.In Unity's networking (assuming you are using Netcode for GameObject instead of the old Mid-Level API MLAPI), you can use
[ClientRpc]
to send updates from the server/host to all clients.Modify the
LoadPlayer
method to call aClientRpc
method that updates the player name on all clients.Do attach this script to your player prefab and link the
username
Text
component accordingly.When you want to set the player's name, call the
LoadPlayer
method. It checks if the code is running on the server and then invokes theClientRpc
method.The
UpdatePlayerNameClientRpc
method is marked with the[ClientRpc]
attribute, indicating that it is a method that the server calls to execute on all clients. It updates theusername
Text component with the provided name.The
IsServer
check makes sure theClientRpc
method is only called by the server, which is necessary for proper synchronization in a multiplayer setting.That should, when a player's name is set on the server, update it across all clients, synchronizing the displayed name in your multiplayer game.
Yes, you are correct: in Unity's Netcode for GameObjects, a spawned object does not automatically inherit its attributes set before the spawn across the network. The initial state of the object as seen by the clients is determined at the point of spawning. Changes made to the object on the server before it is spawned are not automatically propagated to the clients.
To synchronize these initial states or attributes across clients, you would indeed use network variables. Network variables are designed to automatically synchronize their values from the server to all clients.
By setting these variables before spawning the object, you make sure joining players receive the current state of these variables upon connection, thereby reducing the need for numerous RPC calls.