Search code examples
unity-game-engineunity-networking

Unity Netcode Networked GameObject not Appearing on Client


I am trying to build a multiplayer tile-based strategy game. From my understanding, I should create a "Player" GameObject, and then the map should be stored as a collection of GameObjects with a NetworkObject component to sync from client to server.

However, I am having issues syncing GameObjects between the host and the client. When a server is created, only the server should generate the map (map generation code marked). When a player connects, they should get their own game component.

namespace HelloWorld
{
    public class HelloWorldManager : MonoBehaviour
    {
        public GameObject networkedPrefab;

        void OnGUI()
        {
            GUILayout.BeginArea(new Rect(10, 10, 300, 300));
            if (!NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer)
            {
                if (GUILayout.Button("Client")) NetworkManager.Singleton.StartClient();
                if (GUILayout.Button("Server")) {
                    // Generate 'map' here of 10 items
                    for (int i = 0; i < 10; i++) {
                        var go = Instantiate(networkedPrefab);
                        go.transform.position = new Vector2((i - 5), 0);
                        go.gameObject.name = "Circle-" + i;
                    }
                    NetworkManager.Singleton.StartServer();
                } 
            }
            else
            {
                StatusLabels(); 
                SubmitNewPosition(); // Adds button for player to randomly move their position
            }

            GUILayout.EndArea();
        }

static void SubmitNewPosition()
        {
            if (GUILayout.Button(NetworkManager.Singleton.IsServer ? "Move" : "Request Position Change"))
            {
                if (NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsClient )
                {
                    foreach (ulong uid in NetworkManager.Singleton.ConnectedClientsIds)
                        NetworkManager.Singleton.SpawnManager.GetPlayerNetworkObject(uid).GetComponent<HelloWorldPlayer>().Move();
                }
                else
                {
                    var playerObject = NetworkManager.Singleton.SpawnManager.GetLocalPlayerObject();
                    var player = playerObject.GetComponent<HelloWorldPlayer>();
                    player.Move();
                }
            }
        }
    }
}

Here is what I am getting with 0 clients (The map is represented by circles): Map with 0 clients

After adding a client, here is what I get on the server side: enter image description here

... And on the client side I get nothing: enter image description here

Here are the prefabs I used:

enter image description here enter image description here enter image description here

Any help to get things to sync across the server and client would be greatly appreciated.


Solution

  • As your objects are generated at runtime (rather than saved in the scene), you need to call Spawn() on the network object. Adding a NetworkObject is enough if your objects are saved in the scene but dynamically instantiating them at runtime requires a spawn call.

    For your map:

       for (int i = 0; i < 10; i++) {
           var go = Instantiate(networkedPrefab);
           go.transform.position = new Vector2((i - 5), 0);
           go.gameObject.name = "Circle-" + i;
           go.GetComponent<NetworkObject>().Spawn();
       }
    

    As an aside, I think you need to start the server before doing the spawn.