When I create a server and load a scene that Network.Instantiates the player on load the server sees one player. This is good.
When I connect a client to that server and load the same scene that also Network.Instantiates a player. The client see two synced (laggy but synced) players. This is also good.
The problem is the server never gets the clients Network.Instantiate and you only see the host’s player on the server and not the clients.
Any common problems someone sees with this? Thanks.
Thats normal. You would normally do the instantiate on the server and then replace the network id on the network view of the object you instantiated on the client to take over control.
But Network.Instantiate is commonly avoided anyway as it has limitations that hit most applications earlier or later.
Care to show some scripts? Whatever script that does the Network.Instantiating, which is probably on your spawner.
Sure. Thanks for both your interests. I have been looking into doing this myself since I have heard negative things about Network. Instantiate from a few sources.
However here was the original, very simple code I was initially using. This is in a “SceneController” object that I place in each game scene.
[ORIGINAL CODE]
void Start ()
{
if(Network.isClient || Network.isServer)
{
GameObject player = Network.Instantiate(Resources.Load("Prefabs/Player"), GetRespawnPosition(), Quaternion.identity, 0) as GameObject;
}
else
{
GameObject player = Instantiate(Resources.Load("Prefabs/Player"), GetRespawnPosition(), Quaternion.identity) as GameObject;
}
}
I have been looking to do this just using unbuffered RPC calls but I’m a little confused how the “owner” is set when NOT using Network.Instantiate. If the owner is set by who initiated that NetworkView than I thought I might be able to just create the player prefab on the client that just joined and shoot an RPC to everyone else that looks like this that passes the NetworkViewID to them. This what I am thinking now… I haven’t had the opportunity o test it yet, but what do you think?
[NEW IDEA]
void Start ()
{
//Create player locally on each machine
GameObject player = Instantiate(Resources.Load("Prefabs/Player"), GetRespawnPosition(), Quaternion.identity) as GameObject;
if(Network.isClient || Network.isServer)
{
NetworkView netView = GetComponent<NetworkView>() as NetworkView;
netView.RPC("SpawnNetworkPlayer", RPCMode.Others, player.networkView.viewID);
//TODO: If client joined the game late instantiate all objects created by other players
}
}
[RPC]
public void SpawnNetworkPlayer(NetworkViewID netViewID)
{
GameObject netPlayer = (GameObject)Instantiate(Resources.Load("Prefabs/Player"), GetRespawnPosition(), Quaternion.identity);
netPlayer.networkView.viewID = netViewID;
}
I’m trying to make a simple non-authoritative server from scratch so I understand the principles better.
P.S. It was a pain replying to this on my iPad. Sorry for typos.
I don’t fully grasp the concept of manually assigning networkView ID’s either… but I still using Network.Instantiate for my player prefabs, I just use RPC’s for everything else. But I haven’t had any problems with it yet.
OK I got it working with Network.Instantiate. The problem was that I would connect in one scene and then after I went the next scene I was trying to Network.Instatiate in the Start method of the loader. I assume since I connected in the last scene this would be OK, but I noticed when isClient and isServer were both false. However I would see the host’s player moving on the client screen… so I knew they were connected at some point.
This check works on the host machine, but for some reason the client isn’t connected to network anymore at that time. So I put the instantiation into the OnConnectedToServer() callback of the loader in the next scene instead. Everything seems to be working at that point.
I also ran into this problem in my Player prefab when I tried to do a NetworkView.isMine check in the Start() method to turn off some scripts for remote players. I had to move this check to the OnNetworkInstantiate() which makes sense.
So I am happy with these fixes so far… they actually make sense. I just hope I don’t run into too many other problems with Network.Instantiate()… I’m already fearing removing players since I hear Network.Destroy doesn’t remove the Instantiate call from the buffer?
Hi,
I am having some problems with the Network.Instantiate. The connection between Server and Client works perfect. I create a moving cube on the client and one on the server. Everything is synchronized well. Then I disconnect the client from the server and the cube is removed correctly in both server and client instances. My doubt is: how could I remove the server instance on the client? It seems I cannot remove a remote instance 
You mean how woudl you remove the server instance of the prefab object if the server disconnected? If the server disconnected, the game would end and the clients would be booted out, wouldn’t they?
It is true that Network.Destroy() does not get remove the buffered Network.Instantiate call, but thats not really that big of a deal. You should make good use of network groups for your buffered RPC calls, and remove them when necessary with RemoveRPCsInGroup. The bigger problem is that Network.Destroy() does not get buffered, but Network.Instantiate does, so if you for instance, Network.Instantiated a rocket and then Network.Destroyed it on collision, the instantiate would be buffered but the destroy would not, so when a new player connects a crapton of projectiles are going to spawn. However, this can be easily remedied in two ways:
- overload the Network.Destroy() call in an RPC, and buffer that RPC.
- put all projectile network.instantiates and network.destroys in their own group, and periodically dump them all with RemoveRPCsInGroup (I typically do it every 5 seconds or so).