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 GameObject
s 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):
After adding a client, here is what I get on the server side:
... And on the client side I get nothing:
Here are the prefabs I used:
Any help to get things to sync across the server and client would be greatly appreciated.
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.