Hi! I’m new to NetCode and having an issue with syncing between host and client.
Here I’ve made this script to spawn some PlayerObject and name them straight away (I don’t want to use the NetworkManager.PlayerPrefab fields). But the freshly made names appear only on Host side… Clients still have those “playerPrefab(Clone)” names in hierarchy.
Would like to have some help on this one…
Thanks in advance
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Unity.Netcode;
using UnityEngine.SceneManagement;
public class Spawner : NetworkBehaviour
{
public string champName;
private GameObject playerPrefab;
public GameObject[] champList;
public Transform[] SpawnPositions;
private void Awake()
{
int i = 0;
if (NetworkManager.Singleton.IsServer)
{
foreach (NetworkClient client in NetworkManager.Singleton.ConnectedClientsList)
{
SetPlayerChamp();
playerPrefab = champList.Single(d => d.name == champName);
GameObject player = Instantiate(playerPrefab, SpawnPositions[i].position, SpawnPositions[i].rotation);
player.GetComponent<NetworkObject>().SpawnAsPlayerObject(client.ClientId);
// Can't make this next line sync with client :
player.name = "Player " + (i + 1);
// Tried in addition with this rpc but it doesn't work either...
SetNameClientRpc();
i++;
[ClientRpc]
void SetNameClientRpc()
{
player.name = "Player " + (i + 1);
}
}
}
}
void SetPlayerChamp()
{
champName = ChampSelect.ChampionName;
}
}
I would avoid having the RPC as a local function. I’m trying to get my head around how it would work as the player reference is only on the server and I’m not sure how it would match up on the client. Unfortunately I can’t test it as I’m on Unity 2020 and it doesn’t support local function attributes.
Check the RPC is actually run client-side and that the player reference is correct.
Try this RPC call, you’ll need to move the RPC out of the foreach loop and just call it from there instead. I’m assuming all clients have connected at this point.
Works like charm! Thank you guys <3
Here’s the new working code for those in need :
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Unity.Netcode;
using UnityEngine.SceneManagement;
public class Spawner : NetworkBehaviour
{
public string champName;
public GameObject playerPrefab;
public GameObject[] champList;
public Transform[] SpawnPositions;
override public void OnNetworkSpawn()
{
int i = 0;
if (NetworkManager.Singleton.IsServer)
{
foreach (NetworkClient client in NetworkManager.Singleton.ConnectedClientsList)
{
GameObject player = Instantiate(playerPrefab, SpawnPositions[i].position, SpawnPositions[i].rotation);
player.GetComponent<NetworkObject>().SpawnAsPlayerObject(client.ClientId);
i++;
SetNameClientRpc(player, "Player " + i);
}
}
}
[ClientRpc]
private void SetNameClientRpc(NetworkObjectReference player, string newName)
{
Debug.Log("Spawner SetNameClientRpc: " + newName);
((GameObject)player).name = newName;
}
}