- Home /
Networking trouble
Hi everyone.
I've got a problem. I have a multiplayer game, and when it starts i use a function to instantiate the player.
The thing is that the client does exactly what the server does, i mean, if my player in the server turns around and ends up looking at a tree, the client does the same.
This is the code i use to instantiate the players. Please help me i have no clue.
function OnNetworkLoadedLevel () {
//instantiates the player
myPlayer = playerPrefab;
myPlayer = Network.Instantiate(myPlayer, transform.position, transform.rotation, 0);
myPlayer.name = "PlayerNet" + playersCont.ToString();
if(playersCont < 1){
myPlayer.AddComponent("Move");
myPlayer.AddComponent("NetworkView");
}
if(Network.isServer){
//Instatiates a target
myPlayer = targetPrefab;
myPlayer.name = "Target";
myPlayer = Network.Instantiate(myPlayer, new Vector3(50,2.5,80), transform.rotation, 0);
}
}
When the game is running the players are instantiated in client and server, but just the local player has attached a networkview component and the "Move" Script, so, i dont think the script is controlling the other player.
Thanks, regards.
Answer by asafsitner · Mar 14, 2012 at 08:29 AM
That's because you use `Network.Instantiate`. What happens is all network players get an RPC to instantiate the player prefab, and that's it. The other part, where you attach components to it are only executed on the local machine. If you'll check you'll probably see the name of the player hasn't changed as well.
What you should do is write your custom instantiate RPC and within it change the name, attach the components etc.
Also note that you always need to attach a NetworkView component, and that this component has to have the same networkViewID across all connected machines, server and clients in order for it to synchronize correctly. You can assure that by adding a call to `Network.AllocateViewID` outside the instantiation RPC, then sending the resulting viewID as a parameter to the RPC.
It is important to realize that the network owner of an object is the last player to allocate it a viewID. This means that if a player calls Network.AllocateViewID
, they own that ID. So if they send an RPC to everyone else to assign their newly acquired viewID to some object, they become the network owners of that objects, which means they're the only ones writing to the stream of that object (this means that they'll get true
back when getting the `BitStream.isWriting` in OnSerializeNetworkView.
Hi thanks for the answer. I'm a little lost here, because i had another game, and i load the players in the OnNetworkLoadedLevel () function.
I think i know what it is, but just in case i'm mistaken, could you please tell me, the player prefab has a networkview, you said that the networkview ID in the server has to be the same that the networkview ID in the client? if not, it they wont synchronize correctly?
Thanks, i will try what you tell me, in case i cant make it work, do you $$anonymous$$d if i ask you some more questions?
Thanks.
Not at all, although I can't guarantee an answer. :)
You are correct, though. The player prefab has to have the same networkViewID
across all connected machines in order for it to synchronize properly.
If the player prefab comes with a NetworkView
component already, just send an RPC to overwrite it's viewID
with a new one.
Thanks. I found the problem, i have some RPC functions on my $$anonymous$$ain Camera and since it has a NetworkView component it seems like it was synchronized with all cameras in the clients.
One more question, is there any way to do something like this? :
var nView : NetworkView; nView = clone.GetComponent(NetworkView); nView.viewID = 10;
I mean assign a viewID directly.
Thanks
Yes, except that ins$$anonymous$$d of assigning like this:
nView.viewID = 10;
you use Network.AllocateViewID() to reserve an ID. Then, you can pass this around by RPC to all the rest of the clients.
var newID : NetworkViewID = Network.AllocateViewID();
// send the newID as a paramater in the instantiation RPC
var nView : NetworkView;
nView = clone.GetComponent(NetworkView);
nView.viewID = newID;