Search Unity

Instantiating with RPC problem

Discussion in 'Multiplayer' started by virror, Apr 16, 2012.

  1. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    I'm trying to send a RPC to the other clients when i new player logs in telling them that they should instantiate a player model. Problem is, nothing is happening, what have i missed?

    Code (csharp):
    1. void Start ()
    2. {
    3.   if(networkView.isMine != true)
    4.     enabled = false;
    5.  
    6.   Instantiate(mePlayer,new Vector3(10,100,10),mePlayer.transform.rotation);
    7.  
    8.   if(Variables.isMultiplayer) //Multiplayer
    9.   {
    10.     networkView.RPC("SpawnPlayer", RPCMode.OthersBuffered, extPlayer.transform.position, extPlayer.transform.rotation);
    11.   }
    12. }
    13.  
    14. [RPC]
    15. void SpawnPlayer(Vector3 position, Quaternion rotation)
    16. {
    17.   Instantiate(extPlayer, position, rotation);
    18. }
     
  2. w00dn

    w00dn

    Joined:
    Apr 28, 2010
    Posts:
    275
  3. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    That should only be needed if i want to use a network view to later update the transform of the object, right?
    First step is just to make something spawn, no RPC is received at all on the other client that i'm running in unity with full network debug.

    Thanx for the link though, will be helpful later : )

    Edit: Might mention that both clients and server are running locally, and also part of the same firmware.
     
  4. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Anyone?
     
    Last edited: Apr 17, 2012
  5. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Anyone who can help me please? This is really a show stopper : /
     
  6. George Foot

    George Foot

    Joined:
    Feb 22, 2012
    Posts:
    399
    When a new player signs in, presumably you're running the script you pasted above attached to some game object in that player's game? What creates that game object, and what gives it a NetworkView owned by the right player? If the RPC is not getting through, this is the first place I'd look, as the RPC can only run if all the other clients already have the corresponding NetworkView, and if you issue the RPC before they do, it will just get dropped with an error.
     
  7. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    This script is attached to a empty GameObject in the game scene so its always present when the game starts together with a networkView thats also attached to the same empty GameObject. So as soon as the game scene loads, the player is created and another player model is loaded through a buffered RPC call. No errors or anything is reported.
     
  8. w00dn

    w00dn

    Joined:
    Apr 28, 2010
    Posts:
    275
  9. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Ofcourse : ) Starting a server, then connecting one client and then connects a second client.
    I used network.Instantiate before and that worked, but i wanted different models to spawn locally and remotely so i changed it to a RPC and moved it to a separate file that will handle player related stuff.
     
  10. w00dn

    w00dn

    Joined:
    Apr 28, 2010
    Posts:
    275
    any chance you can send me the project or a simplified version of it?
     
  11. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    As soon as i get home, i guess i could put something together : )
    I really appreciate your help!
     
  12. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Haha, silly problem : p
    I forgot to add a networkView to the GameObject were the server script was : p
    But now i have another problem, when player 2 logs in, player 1 sees him, but the buffered call from player 1 wont reach player 2 for some reason. Anything specific i need to do on the server part to get the buffering to work? It should work "out of the box" right?
    Now i have tested running both server, client 1 and client 2 in unity and no one is getting any error.
     
    Last edited: Apr 20, 2012
  13. Other Worlds

    Other Worlds

    Guest

    Joined:
    Mar 16, 2012
    Posts:
    15
    Why aren't you using something like this?

    That will allow the person connecting to retain control over their character across the network (as in, you can use if(networkView.isMine) to have the player alone control their character) and the RPC will just update their details on everyone else's machine.
     
  14. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Well, i dont want to use Network.Instantiate, because i need different prefabs to be spawned depending on if its the other players player im Instantiating or my own. Currently i have this code:

    Code (csharp):
    1.  
    2. public class PlayerHandler : MonoBehaviour {
    3.    
    4.     public GameObject mePlayer;
    5.     public GameObject extPlayer;
    6.    
    7.     private Player[] playerList;
    8.     // Use this for initialization
    9.     void Start ()
    10.     {
    11.         if(networkView.isMine == true)
    12.         {
    13.        
    14.         playerList = new Player[50];
    15.         Instantiate(mePlayer,new Vector3(10,100,10),mePlayer.transform.rotation);
    16.  
    17.         if(Variables.isMultiplayer) //Multiplayer
    18.         {
    19.             NetworkView nView = extPlayer.GetComponent<NetworkView>();
    20.             networkView.RPC("SpawnPlayer", RPCMode.OthersBuffered, nView.viewID, extPlayer.transform.position, extPlayer.transform.rotation);
    21.         }
    22.         }
    23.     }
    24.    
    25.     [RPC]
    26.     void SpawnPlayer(NetworkViewID viewID, Vector3 position, Quaternion rotation, NetworkMessageInfo player)
    27.     {
    28.         GameObject tmpObject;
    29.         tmpObject = (GameObject)Instantiate(extPlayer, position, rotation);
    30.         NetworkView nView = tmpObject.GetComponent<NetworkView>();
    31.         nView.viewID = viewID;
    32.        
    33.         for(int i = 0; i < playerList.Length; i++)
    34.         {
    35.             if(playerList[i] == null)
    36.             {
    37.                 playerList[i] = new Player(player.sender);
    38.                 playerList[i].PlayerObject = tmpObject;
    39.                 break;
    40.             }
    41.         }
    42.     }
    43.    
    44.     [RPC]
    45.     void RemovePlayer(NetworkMessageInfo player)
    46.     {
    47.         for(int i = 0; i < playerList.Length; i++)
    48.         {
    49.             if(playerList[i] != null)
    50.             {
    51.                 if(playerList[i].NetPlayer.guid == player.sender.guid)
    52.                 {
    53.                     playerList[i] = null;
    54.                     break;
    55.                 }
    56.             }
    57.         }
    58.     }
    59. }
    60.  
     
  15. Other Worlds

    Other Worlds

    Guest

    Joined:
    Mar 16, 2012
    Posts:
    15
    I'd recommend still using Network.Instantiate, but attach a script that basically says if the networkview isn't ours, disable the renderer and instantiate the replacement object and child it to the network object. That way, you preserve the player's networkview and get to have the separate object visible on other machines.

    Out of curiosity, what is the situation here? Why do you need different objects displayed on the other players' games?
     
  16. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Very simple, for the player, i spawn a GameObject with camera, listener, scripts and stuff. But for the other players GameObject, i just want a player model.

    And even it it were so that something should not work out with my method, it should still send a RPC to the latest client from the buffered list.
     
    Last edited: Apr 20, 2012
  17. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    There's good reason you don't want to child objects for the sake of keeping networkView intact; what if the other prefab dynamically changed dimensions or scale? Converting back and forth beteeen coordinate spaces or adjusting for scale and height differences is not an answer. Not to mention you cannot disable a script's ability to take RPC calls, so you'd have to have remove those scripts dynamically, but then you'd get RPC not received by any object errors unless you're careful. Much simpler just to instantiate a different prefab. I do much the same thing in my projects.
     
    Last edited: Apr 20, 2012
  18. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    The first thought that comes to my mind is that because you're calling the RPC in Start(), the network might not have connected yet, so the RPC's being sent off to nowhere, but then the first player shouldn't be able to see the second player either. I'm on the bus at the moment, I'll take a closer look when I get home.
     
  19. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Thanx for your time : )
    The player connects in scene 0, then on OnConnected scene 1 loads, and thats were this Class are. So its 100% guaranteed that the player is connected, i have also checked the server and both RPCs arrives there.
     
  20. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    See, that could be a problem. As soon as a player connects to a server, all the buffered RPCs are sent from the sever and ran on the client, regardless of what scene they the client is in. By the time you load scene 1, the RPCs have probably already been called. Check your project hierarchy, see if the player has actually spawned but falling off stage or something.

    EDIT: or in fact because scene 1 has not loaded, the object this script is attached to may not have been created yet, so the RPC could have just not been received.

    If this is the case, you'll have to turn MessageQueue off before you connect, and turn it back on when you load the new scene so that stuff spawns in the right place.

    EDIT 2: clarified a bunch of stuff
     
    Last edited: Apr 20, 2012
  21. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Ohh, will try that, sound very logical : )
     
  22. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    Yeah I don't like buffered RPCs because you can run into problems like timing that's fairly hard to diagnose when you're not used to it. I cheat around this by calling RPCs to the server to send all the other players' info after a player connects and spawn them that way, and not using buffered RPC calls.
     
  23. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Smart! Will try that as well : ) Thanx a lot for the help and great hints.
    No its time for bed : p
     
  24. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Always some problem : /
    Tried this way: When connecting, player sends RPC to all connected players, non buffered to spawn player.
    Then it sends a RPC to the server, the server then loops it player list and sends a RPC to all players except the player it got the RPC from, this RPC tells the other clients so send a spawn RPC to this new client. Problem is that RPCMode.Server dont seems to work very well, because the server wont receive that RPC. Anything special about trying to send RPC to the server only?
     
  25. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    Nope, works fine.
     
  26. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    Not sure why that would be...it seems to work fine for me as well.

    As a side note, why go to all the trouble? When you send RPCs to all other players, just have them send an RPC back in the same function to spawn themselves.
     
  27. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    True, but i still want to make the server thing work for future uses.
     
  28. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Gahh! Still wont work : / Now i send a RPC to all spawning my player, then i send a "spawn request" to other players making them send a RPC back to spawn their player on my client. The first two steps works, but the last RPC that will spawn their player at my client wont reach my client, the server registers it, but it wont arrive... Also the "if(networkView.isMine == true)" wont work for some reason. Always registers as false.

    Code (csharp):
    1.  
    2. public class PlayerHandler : MonoBehaviour {
    3.    
    4.     public GameObject mePlayer;
    5.     public GameObject extPlayer;
    6.    
    7.     private Player[] playerList;
    8.     // Use this for initialization
    9.     void Start ()
    10.     {
    11.         Network.isMessageQueueRunning = true;
    12.         //if(networkView.isMine == true)
    13.         {
    14.             playerList = new Player[50];
    15.             Instantiate(mePlayer,new Vector3(10,100,10),mePlayer.transform.rotation);
    16.    
    17.             if(Variables.isMultiplayer) //Multiplayer
    18.             {
    19.                 NetworkView nView = mePlayer.GetComponent<NetworkView>();
    20.                 networkView.RPC("SpawnPlayer", RPCMode.Others, nView.viewID,
    21.                     mePlayer.transform.position, mePlayer.transform.rotation, Variables.gPlayerName);
    22.                 networkView.RPC("UpdatePlayer",RPCMode.Others);
    23.             }
    24.         }
    25.     }
    26.    
    27.     [RPC]
    28.     void SpawnPlayer(NetworkViewID viewID, Vector3 position, Quaternion rotation, string name,
    29.         NetworkMessageInfo player)
    30.     {
    31.         GameObject tmpObject;
    32.         tmpObject = (GameObject)Instantiate(extPlayer, position, rotation);
    33.         NetworkView nView = tmpObject.GetComponent<NetworkView>();
    34.         nView.viewID = viewID;
    35.        
    36.         for(int i = 0; i < playerList.Length; i++)
    37.         {
    38.             if(playerList[i] == null)
    39.             {
    40.                 playerList[i] = new Player(player.sender);
    41.                 playerList[i].PlayerObject = tmpObject;
    42.                 playerList[i].Name = name;
    43.                 break;
    44.             }
    45.         }
    46.         tmpObject.GetComponent<GUIText>().text = name;
    47.     }
    48.    
    49.     [RPC]
    50.     void UpdatePlayer(NetworkMessageInfo player)
    51.     {
    52.         NetworkView nView = mePlayer.GetComponent<NetworkView>();
    53.         networkView.RPC("SpawnPlayer", player.sender, nView.viewID, mePlayer.transform.position,
    54.                      mePlayer.transform.rotation, Variables.gPlayerName);
    55.     }
    56.    
    57.     [RPC]
    58.     void RemovePlayer(NetworkMessageInfo player)
    59.     {
    60.         for(int i = 0; i < playerList.Length; i++)
    61.         {
    62.             if(playerList[i] != null)
    63.             {
    64.                 if(playerList[i].NetPlayer.guid == player.sender.guid)
    65.                 {
    66.                     playerList[i] = null;
    67.                     break;
    68.                 }
    69.             }
    70.         }
    71.     }
    72. }
    73.  
     
  29. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    I can't say exactly why the RPC won't reach back to the client if the server receives it, but if I remember correctly (EDIT: just tested, it is indeed), NetworkMessageInfo.sender gives you where the message came from, this means that since all RPCs are routed through the server, on any given client NetworkMessageInfo.sender will always give you 0 (the server). This is why the RPCs are not reaching the intended client. You'll have to send a NetworkPlayer variable yourself if you want an RPC to come back your way if you're a client. (This is terrible documentation on Unity's part, don't fret yourself too much over it. Took me a good week to figure this out, and I believe someone else on the forum helped)

    The Network.isMine bug is a little weirder, the only thing that comes to mind is that unless the server's already initiated, it will always return false; but from what I understand this script gets called after you already start a server, so...I don't get it. I'll note here that for NetworkViews already in the scene the Server will always be the owner.

    A third problem I came across in your code is you don't allocate NetworkViewIDs. A prefab with a NetworkView won't get assigned anything if you just locally Instantiate it; this is why Network.Instantiate exists.

    Since we're doing it manually though,
    Code (csharp):
    1.  
    2. void Start ()
    3. {
    4.     Network.isMessageQueueRunning = true;
    5.     //if(networkView.isMine == true)
    6.         {
    7.             playerList = new Player[50];
    8.             Instantiate(mePlayer,new Vector3(10,100,10),mePlayer.transform.rotation);
    9.  
    10.             if(Variables.isMultiplayer) //Multiplayer
    11.             {
    12.                 NetworkViewID newID = Network.AllocateViewID();// <------- You have a allocate a new ID
    13.  
    14.                 NetworkView nView = mePlayer.GetComponent<NetworkView>();
    15.                 nView.viewID = newID;// <------------ Then assign it to your view
    16.  
    17.                 networkView.RPC("SpawnPlayer", RPCMode.Others, nView.viewID, //<---- And then you can send the viewID off
    18.                     mePlayer.transform.position, mePlayer.transform.rotation, Variables.gPlayerName);
    19.  
    20.                 networkView.RPC("UpdatePlayer",RPCMode.Others);
    21.             }
    22.         }
    23.     }
    24.  
    Whoever allocated the ID is considered the owner when you assign the ID to a NetworkView.
     
    Last edited: Apr 22, 2012
  30. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Yes, i remember the thing about NetworkMessageInfo.sender, i think its a crazy behavior : p
    I thought i allocated a new networkId, but i guess i accidentally removed that code when changing something else...
    Thanx a LOT for all the help : )
     
  31. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    When i thought i started to get a grip on this multiplayer thing, it stopped working again : /
    Following errors occur on the server:

    Running as server. Player ID is 0.
    New connection established (127.0.0.1:1299)
    Network protocol version 0 connected
    New scope index 0 is now in scope for SceneID: 1 Level Prefix: 0
    Allocated 2 batches of size 50 for player 1
    Sent initalization to player 1
    Received RPC 'SpawnPlayer'- mode 1 - sender 127.0.0.1:1299
    View ID SceneID: 2 Level Prefix: 0 not found during lookup. Strange behaviour may occur
    Could't invoke RPC function 'SpawnPlayer' because the networkView 'SceneID: 2 Level Prefix: 0' doesn't exist
    Received RPC 'UpdatePlayer'- mode 1 - sender 127.0.0.1:1299
    View ID SceneID: 2 Level Prefix: 0 not found during lookup. Strange behaviour may occur
    Could't invoke RPC function 'UpdatePlayer' because the networkView 'SceneID: 2 Level Prefix: 0' doesn't exist

    Seems like a problem because of different SceneIDs? Server is on Scene 0 and client on Scene 1, but it worked before. I have stubs for the RPCs on the server as well. Client starts in scene 0 and when connection is made, it loads scene 1, so no RPCs or anything will fire before a connection is made. Sorry for the long post : )
    Note: Unity have a lot of spelling errors in their network log : p

    Client code
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class PlayerHandler : MonoBehaviour {
    6.    
    7.     public GameObject mePlayer;
    8.     public GameObject extPlayer;
    9.    
    10.     private Player[] playerList;
    11.     private GameObject player;
    12.    
    13.     public GameObject Init()
    14.     {
    15.         Network.isMessageQueueRunning = true;
    16.         //if(networkView.isMine == true)
    17.         {
    18.             playerList = new Player[50];
    19.             player = (GameObject)Instantiate(mePlayer,new Vector3(10,10,10),mePlayer.transform.rotation);
    20.             if(!Variables.isNewGame)
    21.                 LoadPlayer();
    22.    
    23.             if(Variables.isMultiplayer) //Multiplayer
    24.             {
    25.                 NetworkViewID newID = Network.AllocateViewID();
    26.                 NetworkView nView = mePlayer.GetComponent<NetworkView>();
    27.                 nView.viewID = newID;
    28.                 networkView.RPC("SpawnPlayer", RPCMode.Others, newID,
    29.                     mePlayer.transform.position, mePlayer.transform.rotation, Variables.gPlayerName);
    30.                 networkView.RPC("UpdatePlayer",RPCMode.Others, Network.player);
    31.             }
    32.             return player;
    33.         }
    34.     }
    35.    
    36.     public NetworkPlayer GetNetworkPlayerByName(string name)
    37.     {
    38.         for(int i = 0; i < playerList.Length; i++)
    39.         {
    40.             if(playerList[i] != null)
    41.             {
    42.                 if(playerList[i].Name == name)
    43.                 {
    44.                     return playerList[i].NetPlayer;
    45.                 }
    46.             }
    47.         }
    48.         NetworkPlayer a = new NetworkPlayer();
    49.         return a;
    50.     }
    51.    
    52.     [RPC]
    53.     void SpawnPlayer(NetworkViewID viewID, Vector3 position, Quaternion rotation, string name,
    54.         NetworkMessageInfo player)
    55.     {
    56.         GameObject tmpObject;
    57.         tmpObject = (GameObject)Instantiate(extPlayer, position, rotation);
    58.         NetworkView nView = tmpObject.GetComponent<NetworkView>();
    59.         nView.viewID = viewID;
    60.        
    61.         for(int i = 0; i < playerList.Length; i++)
    62.         {
    63.             if(playerList[i] == null)
    64.             {
    65.                 playerList[i] = new Player(player.sender);
    66.                 playerList[i].PlayerObject = tmpObject;
    67.                 playerList[i].Name = name;
    68.                 break;
    69.             }
    70.         }
    71.         tmpObject.GetComponent<GUIText>().text = name;
    72.     }
    73.    
    74.     [RPC]
    75.     void UpdatePlayer(NetworkPlayer player)
    76.     {
    77.         NetworkView nView = mePlayer.GetComponent<NetworkView>();
    78.         networkView.RPC("SpawnPlayer", player, nView.viewID, mePlayer.transform.position,
    79.                      mePlayer.transform.rotation, Variables.gPlayerName);
    80.     }
    81.    
    82.     [RPC]
    83.     void RemovePlayer(NetworkMessageInfo player)
    84.     {
    85.         for(int i = 0; i < playerList.Length; i++)
    86.         {
    87.             if(playerList[i] != null)
    88.             {
    89.                 if(playerList[i].NetPlayer.guid == player.sender.guid)
    90.                 {
    91.                     playerList[i] = null;
    92.                     break;
    93.                 }
    94.             }
    95.         }
    96.     }
    97. }
    98.  
    Server code
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class ServerScript : MonoBehaviour {
    6.    
    7.     private int terrainSeed;
    8.    
    9.     public void Init ()
    10.     {
    11.         terrainSeed = UnityEngine.Random.Range(0, 100000);
    12.     }
    13.    
    14.     //Player connected to server
    15.     void OnPlayerConnected(NetworkPlayer player)
    16.     {
    17.         Lumos.Event("Player connected");
    18.     }
    19.    
    20.     //Player disconnected
    21.     void OnPlayerDisconnected(NetworkPlayer player)
    22.     {
    23.         Network.RemoveRPCs(player);
    24.         Network.DestroyPlayerObjects(player);
    25.         networkView.RPC("RemovePlayer", RPCMode.All);
    26.     }
    27.    
    28.     //Server started
    29.     void OnServerInitialized()
    30.     {
    31.         Lumos.Event("Server started");
    32.     }
    33.    
    34.     [RPC]
    35.     void SendSeed(NetworkMessageInfo player)
    36.     {
    37.         networkView.RPC("GetSeed", player.sender, terrainSeed);
    38.     }
    39.    
    40.     [RPC]
    41.     void UpdatePlayer(NetworkMessageInfo player){}
    42.    
    43.     [RPC]
    44.     void SpawnPlayer(NetworkViewID viewID, Vector3 position, Quaternion rotation, string name,
    45.         NetworkMessageInfo player){}
    46. }
    47.  
     
  32. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Anyone?
     
  33. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    Sorry for my late response Vir, was busy coding my own game and trying to understand what the hell my artists are talking about.

    Looks like you've updated your code quite a bit, so let me see if I can dig in there. Where exactly are you sending an RPC to the client? I do not see it on your server code, so I'm assuming your Lumos script has something to do with it. If Lumos is, say, on a different GameObject and sending the RPC with a separate NetworkView of ID "Scene 2" (SceneID in this case just means that it is a NetworkViewID statically put in the scene, instead of dynamically allocated at runtime, and as such uses its own set of numbers), then naturally it will fail to find an RPC located on the object with the NetworkViewID of "Scene 1".
     
  34. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Hehe, no problem. I don't expect anyone to drop anything just to help me : p
    Server is never sending a RPC, only RPC call is from
    Code (csharp):
    1.  
    2. networkView.RPC("SpawnPlayer", RPCMode.Others, newID,
    3.  
    4.                     mePlayer.transform.position, mePlayer.transform.rotation, Variables.gPlayerName);
    5.  
    6.                 networkView.RPC("UpdatePlayer",RPCMode.Others, Network.player);
    7.  
    but the server complains about not finding them.
     
  35. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    And that should teach me to open my mouth before I figure out what I'm talking about :D

    Yeah the machine receiving RPC will complain about not finding targets, which means your client sent an RPC, and the server is not finding the corresponding NetworkViewID on itself. So check what NetworkView you're sending the RPC from on the client and make sure the same ID exists on the server.
     
  36. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Hmm, but it worked before. I use multiple NetworkViews on the client (of course) but only one NetworkView on the server, but you are telling me this setup is impossible? I need one NetworkView for each one on the client? Seems like a very big limitation to me if that's the case : /
     
  37. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    The networkview needs to exist in the scene on server and client side. If not it won't work.
    1 view on the server and multiple on the client, has never worked and will never work.
     
  38. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    It kinda half works. If you're just sending info from client to server all you need to do is keep a reference to the one NetworkView that is linked up to the server, i.e. the one with NetworkViewID "Scene 1", and call all your RPCs through that NW, but then you might as well not have the other NetworkViews at all. Obviously if you want it to work the other way around, I suppose you could implement a script that catches the RPCs coming from the server and route it proper GO.
    I'm curious to know what the other NetworkViews on the client are doing? They're not linked with anything, so they're just dangling?
     
    Last edited: May 10, 2012
  39. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Hmm, looks like this is not designed to work well with a separate server implementation : /
    Well, every script that wants to send a RPC needs a NetworkView right? That's why there is multiple NetworkViews.
    What would the best solution be? To only use one NetworkView and then create references to that in the other scripts that needs to send RPCs?

    Thanks a LOT for all the help so far, i wish i could repay you : )
     
  40. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    Think of NetworkView as a door. Multiple doors can't come out the other side through the same door, but why would you need to? You can send all the RPCs through the same door. The only limitation here is that whatever RPC you call must be on a script on the same GO as the NetworkView, then you can route it from there.

    I'm learning Unity myself, like I said, so it's not like I'm not getting anything out of this :D Now if I can only figure out how to attach equipment and stuff to a model...I'm a complete noob when it comes to dealing with 3d art.
     
  41. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Thanks a lot, i will try that : )

    Only thing i know about that stuff is either have all the equipment in the model or to have a few "attach bones" that you can add a gameobject as a child to.
     
  42. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    Bah, don't worry about it, I'm just ranting :( I'm sure I'll figure it out given time. I just rather not have to go through learning the whole animation process while I'm at it :D Not that I mind, but I'd like to finish my project on time for once damn it.
     
  43. George Foot

    George Foot

    Joined:
    Feb 22, 2012
    Posts:
    399
    Be careful with the door analogy - NetworkViews exist on, and send data directly to, all of the clients. It's more like a wormhole, or a link between parallel universes - things you do to a NetworkView on the owner get echoed on the other machines (be they clients or servers). Every machine in the session should have an identical set of NetworkViews.

    RPC is a bit different though because anybody can send an RPC on any NetworkView, whether they own it or not, and the sender controls the target machine(s). Still, the same views should exist on all machines in the session. The easiest way to ensure this is to use Network.Instantiate.
     
    Last edited: May 10, 2012
  44. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    A much better analogy. Thanks Mr. Foot!
     
  45. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    You don't need 1 nview per script, you can do multiple things with 1 nview.
     
  46. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Ok, back to this after some terrain stuff.
    I get the point now, but how do i manually set the ViewID?
    Like e.g. myViewID = 1?
    Using AllocateVIewID() wont work because it sets different ids on the server and client.
    Server gives 1 and client gives 50.
     
  47. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Solved it by assigning both server and client a empty ViewID so both gets 0 : p
    Now the server crashes as soon as i try to connect a second client, even editor crashes : /
     
  48. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    I'm not exactly sure what you're trying to do here...If you're assigning IDs then one of the machines should be using AllocateViewID, since that's how Unity determins which machine "owns" the View, but more importantly the system reserves that one ID across all machines. Ideally you'd have 1 (and only one, across all scenes, and just call DontDestroyOnLoad on it so it's always around) NetworkView already in the scene and send RPCs through that one view to instantiate objects and send the allocated ID through. Then you just set the NetworkViewID like normal.
     
  49. virror

    virror

    Joined:
    Feb 3, 2012
    Posts:
    2,963
    Im only using one NetworkView on the server and one on the client. Problem was that when i tried to use AllocateViewID() the client and server got different ones because of some reason, maybe because they were in different scenes. Now im making sure that they are both 0 by assigning a empty ViewID to them. Might not be a neat solution, but it works : )
     
  50. Bluntweapon

    Bluntweapon

    Joined:
    Feb 24, 2012
    Posts:
    158
    When you Allocate a ViewID, the game reserves that particular ID across the network, so that you can never get the ID again when you use another AllocateViewID. This is an inherent property of AllocateViewID, and a behaviour you want. If you want to know which ID has been allocated on another machine, you'll have to send the ID using an RPC.

    Are you trying to set the ID for the one NetworkView that's already in the scene?