one small tip that took me forever to work out for unity multiplayer:
never use Network.Instantiate. It's a buffered call that you can never get rid of. Even if you do a Network.Destroy - the instantiation call will persist when new clients join, but the network.destroy will not.
Every time you spawn a new object via code, I've found the best results is to do something like the following:
Code:
box
{
public GameObject boxPrefab;
void Update()
{
if(Network.isServer)
{
if(Time.time>100)
{
networkView.RPC("Destroy", RPCMode.All, this.networkView.networkViewID);
}
}
}
public void Spawn(Vector3 pos)
{
if(Network.isServer)
{
NetworkViewID newID = NetworkView.AllocateID();
// any other server only config goes here
networkView.RPC("SpawnBox", RPCMode.All, pos, newID);
}
}
[RPC]
void SpawnBox(Vector3 pos, NetworkViewID newViewID)
{
GameObject newBox = GameObject.Instantiate(boxPrefab, pos, rot, whatevs) as GameObject;
newBox.networkView.networkViewID = newViewID;
}
[RPC]
void Destroy(targetNetworkViewID)
{
GameObject target = NetworkView.Find(targetNetworkViewID).gameObject;
GameObject.Destroy(target);
}
/*
This is only run on the Server, and it is run each time a player connects.
The logic behind this is that, if this box object exists on the server,
then it must exist. So create this object on the new client.
*/
OnPlayerConnect(NetworkPlayer player)
{
// I forget if you can RPC players directly, but if you can't there's a similar call somewhere
networkView.RPC("SpawnBox", player, this.transform.position, this.networkView.networkViewID);
}
}
In short,
the publicly accessible spawn function is what you call to spawn objects. It deals with making sure everyone ends up with the same networkID.
the RPC spawn function creates a gameobject locally for everyone but sets the object to have the same viewID.
The onPlayerConnect will create objects that already exist on the new client
The destroy will destroy the object on all clients who are currently connected (including the server).
So if you have one box, and run the Spawn() twice, you create two boxes on all current players. A new player joins, there are three boxes to run OnPlayerConnect, they all create copies on the new player. The server Destroys one box, so all currently connected players have that box be destroyed. A new player joins, this time there are only two boxes alive, so the server creates copies of those two boxes on the new player.
Which may sound like the most simple thing in the world, or the stupidest. But I never found any of this documented anywhere, so I just continually had pains with new players being able to see phantom objects that weren't destroyed by Network.Destroy or RemoveAllRPCs or whatever.
Finally, you have to treat objects that were initialised in the scene differently (as opposed to created by code at runtime). I just manually flag objects that are created in the scene, and then when doing a destroy, I make the destroy call RPCMode.AllBuffered. It's messy, but it works.
I hope any of what I said is of any help at all, because unity networking is a complete fucker sometimes.