Using Network.Instantiate and NetworkView to reflect players views


after few days working on understanding how Unity networking actually work I have some troubles.

I try to do this in order to learn how networking actually works in Unity.

Imagine all you see in the game is a cube. This cube has a color and you can change this color.
Now imagine that you can have up to 4 people in the game. Each one sees his own cube but also cubes of the other players. The main cube (the local player’s one) is big and at the middle of the screen. The others are little and on the side… like a “view of what color the other are seeing”.

So I have a class that performs the match making (it works fine). In it I keep the list of every players connected and add them a “network ID” in order to know who is who.
When every players are connected thanks to the matchmaking class I call a RPC method to warn them that the game will start. Then I use a Network.Instantiate to instantiate the cube of each players in local and warn every others that a new cube has to be instantiated.

In the cube script I check the OnNetworkInstantiate method to know if the newly instantiated cube is local or remote (via networkView.isMine). If it’s local I scale it big and put it at the middle of the screen. But if it’s a remote one I put it somewhere on the screen accordingly to the player it depends of.

Here is my problem: in the NetworkMessageInfo I receive, it seems that every Instantiate calls are made from the host… so I can’t identify who the cube is meant to represent.

This long post for this question: Is there a way to exactly know who has asked to instantiate a specific object in order to visually affect the right object in scene? Or am I completely stupid and I’m in the wrong direction missing all the good stuff and bananas?

Thank you.

Here is what I do in OnNetworkInstantiate:

 private void OnNetworkInstantiate(NetworkMessageInfo info)
   if ( networkView.isMine == true )
     transform.position = new Vector3();
     transform.localScale = new Vector3(10,10,10);
     int pos = 0;
     List connected_players = GameObject.Find("Network").GetComponent().connected_players;
     foreach( ConnectedPlayer cp in connected_players )
       // checks if the sender is the current network_player in list
       if ( cp.network_player == info.sender ) 
         // here pos is always 0 on clients (the first in list is the host)
         transform.position = new Vector3( 15, pos * 2.5f, 42 ); 
         transform.localScale = new Vector3( 2,2,2 );
         // changing name to identify remote object in the hierarchy += "NET-" + cp.network_id.ToString();


Where I instantiate the cube: I wait to receive the RPC call telling me that every one is ready to play then I instantiate the networked cube:

 public void OnEveryPlayersReady()
   if ( cube_prefab != null )
   Network.Instantiate(cube_prefab, new Vector3(), new Quaternion(), 0);


Maybe I was unclear in my question. The Network.Instantiate is called by players (not only host) once they’ve received the RPC call of OnEveryPlayersReady(). Every player instantiate the right number of cube. networkView.isMine works perfectly fine. But as info.sender only returns me the host I can’t tell what player is linked to what cube… so I can’t set cube’s position correctly.

actually all clients are connected to server, not to each other. so calling an RPC to all means calling RPC to server for it calls it to all others.

instead of get NetworkMessageInfo, just use

to get real player of each cube.

So I found this on Unity forums.

There you can read that clients only know about the server. No matter what. Everything you will do from client (even an RPC call from client to client) will in fact be relayed by the server. That’s why, from a client point of view, it’s always the server / host who asks for a NetworkInstantiate…

I think that solves my problem as long as I will be using RPC calls now. In the documentation it’s clearly explained that RPC cost a lot more than NetworkView sync… that makes me sad. Banana.