Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[BUG?] Couldn't send RPC function

Discussion in 'Scripting' started by Defiled, Jun 24, 2014.

  1. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    Greetings, i was curious if some one could help me on a problem that I'm having.
    I'm currently working on networking for my game, im trying to avoid network.instantiate because i only want to instantiate the player on the networks of others that can actually see them, rather than everyone on the server.
    I'm doing this by sending an rpc to the player that he can spawn and checking on the server if there's someone close to him, if there is send him an rpc about this player's location etc.
    that's working perfectly fine, the problem is when a player leaves the server I get the error "Couldn't send RPC function 'UpdateMovementRPC'" everytime a player disconnects from the server.. even though im double checking if the player actually exists on the server

    the code i will provide below,

    Serverscript on client:
    Code (CSharp):
    1.  
    2. public List<Transform> ICanSeeYou = new List<Transform>();
    3.   void FixedUpdate()
    4.    {
    5.      var PlayerObjects = GameObject.FindGameObjectsWithTag("Player");
    6.  
    7.      for (int i = 0; i < PlayerObjects.Length; i++)
    8.      {
    9.        if(PlayerObjects[i] != null && PlayerObjects[i].transform.name != transform.name)
    10.        {
    11.          if(ICanSeeYou.Contains(PlayerObjects[i].transform) == false && Vector3.Distance(transform.position,PlayerObjects[i].transform.position) < 10)
    12.          {
    13.            ICanSeeYou.Add(PlayerObjects[i].transform);
    14.            ServerScript.Create(transform.name, PlayerObjects[i].transform.position, PlayerObjects[i].transform.name);
    15.          }
    16.  
    17.          if(ICanSeeYou.Contains(PlayerObjects[i].transform) == true && Vector3.Distance(transform.position,PlayerObjects[i].transform.position) > 10)
    18.          {
    19.            ICanSeeYou.Remove(PlayerObjects[i].transform);
    20.            ServerScript.Delete(transform.name, PlayerObjects[i].transform.name);
    21.          }
    22.        }
    23.      }
    24.      ServerScript.UpdateMovement(Owner.guid, transform.position);
    25.    }
    26.  
    Serverscript:
    Code (CSharp):
    1.  
    2.  
    3.   void OnPlayerConnected(NetworkPlayer player)
    4.    {
    5.      if(GameObject.Find(player.guid) != null)
    6.        Destroy(GameObject.Find(player.guid));
    7.  
    8.      Object E = Instantiate(PlayerModel,Vector3.zero,PlayerModel.rotation);
    9.      E.name = player.guid;
    10.      GameObject.Find(player.guid).GetComponent<Server_Instantiated_Information>().Owner = player;
    11.      Create (player.guid, Vector3.zero, player.guid);
    12.    }
    13.  
    14.    void OnPlayerDisconnected(NetworkPlayer player)
    15.    {
    16.      List<Transform> list = GameObject.Find(player.guid).GetComponent<Server_Instantiated_Information>().ICanSeeYou;
    17.  
    18.      for(int i = 0; i < Network.connections.Length; i++)
    19.      {
    20.        for(int ii = 0; ii < list.Count; ii++)
    21.        {
    22.          if(list[ii].name == Network.connections[i].guid)
    23.          {
    24.            GameObject.Find(list[ii].name).GetComponent<Server_Instantiated_Information>().ICanSeeYou.Remove(GameObject.Find(player.guid).transform);
    25.            Delete (Network.connections[i].guid, player.guid);
    26.            Network.RemoveRPCs(player);
    27.          }
    28.          if(list[ii] == null)
    29.            Destroy(list[ii]);
    30.        }
    31.      }
    32.      Destroy(GameObject.Find(player.guid));
    33.    }
    34.  
    35. public void UpdateMovement(string owner, Vector3 position)
    36.     {
    37.         Server_Instantiated_Information script = GameObject.Find(owner).GetComponent<Server_Instantiated_Information>();
    38.         for(int i = 0; i < Network.connections.Length; i++)
    39.         {
    40.             for(int ii=0; ii < script.ICanSeeYou.Count; ii++)
    41.             {
    42.                 if(Network.connections[i].guid == script.ICanSeeYou[ii].name && GameObject.Find(owner).transform != null && GameObject.Find(Network.connections[i].guid).transform != null && Network.connections[i] != null)
    43.                 {
    44.                     networkView.RPC("UpdateMovementRPC",Network.connections[i], owner, position);
    45.                 }
    46.             }
    47.         }
    48.     }
    The deleting and spawning of players works perfectly fine, no errors..
    but even though I'm double checking to see if the player is existing on the server and network, it sitll outputs an error when the player leaves the server
     
    Last edited: Jun 24, 2014
  2. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
    Lol, no offense buy your code is very confusing.
    The variable names aren't very descriptive either.

    Just create a static list or dictionary where you keep all the connected players inside.
    Register it on connection, and remove it on disconnection.
    Then send the rpc when the list/dictionary contains that user. o.o

    u can add more information to that list by having a wrapper class
    that contains the networkplayer & the aditional info.

    Btw: Don't use GameObject.Find, there are better ways to target an Object.
     
  3. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    Well the script atm is just a rough script, im just testing things but the problem I'm having is that the script is executing an rpc on a user that left the server even tho im checking if that player is still in the server using the unity function ; Network.connections , it should never send that rpc because im checking on the server if that player exists, it feels like the function is going before the network connections updates
     
  4. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
    What rpc is being sent to that user? o:
    Give me the line number
     
  5. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    Code (CSharp):
    1.  
    2. if(Network.connections[i].guid == script.ICanSeeYou[ii].name && GameObject.Find(owner).transform != null && GameObject.Find(Network.connections[i].guid).transform != null && Network.connections[i] != null)
    3. {
    4.    networkView.RPC("UpdateMovementRPC",Network.connections[i], owner, position);
    5. }
    6.  
    'Serverscript:' line 44
     
  6. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    So I'm basically sending the information to client but before that im checking if client actually exists, and according to the script he does.. but I still get the "couldn't send rpc" error
     
  7. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    Not reading the wall of text so sorry, just putting in some suggestions right here.

    1. The serverscript on the client does not have a method named "UpdateMovementRPC", did you just missed to post it here?
    2. The method on the client needs to be named exactly "UpdateMovementRPC", make sure thats true!
    3. Make sure that certain method got the [RPC] attribute attached!
     
  8. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    havent added all the code here, the updatemovement is called perfectly on all clients and everything works, its just that when a player leaves, the code tries to send him the rpc and it gives the error, and i have no idea how to solve it. I even tried stuff like
    Code (CSharp):
    1. if(Network.connections[i].guid == script.ICanSeeYou[ii].name && GameObject.Find(owner).transform != null && GameObject.Find(Network.connections[i].guid).transform != null && Network.connections[i] != null)
    and putting the rpc send code after that check, but that doesn't solve it
     
  9. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    Let me rephrase my question, how to i send an rpc to a client that is in the Network.connections list every fixedframe, and when that player disconnects it won't give an error?
    Because this is really the issue.
     
  10. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
    You could just catch the exception, since it doesn't happen often when someone leaves. o.o
     
  11. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    How would I "catch" it?
     
  12. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
  13. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    Oh I've actually tried to do that once, but couldnt figure out what kind of exception 'Couldn't send RPC function' was and was hoping i could figure out what was causing the problem if the problem was on my side, do u happen to know what kind of an exception warning the Couldn't send RPC function is?
     
  14. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    Code (CSharp):
    1. try
    2. {
    3.     if(Network.connections[i].guid == script.ICanSeeYou[ii].name && GameObject.Find(owner).transform != null && GameObject.Find(Network.connections[i].guid).transform != null && Network.connections[i] != null)
    4.     {
    5.  
    6.         networkView.RPC("UpdateMovementRPC",Network.connections[i], owner, position);
    7.     }
    8. }
    9. catch(System.Exception e)
    10. {
    11.     Debug.LogException(e, this);
    12. }
    does not seem to catch it ;'(
    bleh, might just switch to network.instantiate, ive used this before and know for a fact it doesn't give the error, but then i'll be spawning the character on everyone's game which wasnt my intention, trying to save as much bandwidth as possible..
     
  15. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
    You don't have to debug the exception, since you're ignoring this error.
    Code (CSharp):
    1. try
    2. {
    3.  
    4. } catch { }
    But it would probably be UnityEngine.UnityException

    I'm suggesting you to catch the exception, since you can't really prevent this from happening.
    The RPC gets sent before the player disconnects, because it takes time for the rpc to arrive.
     
  16. Defiled

    Defiled

    Joined:
    Feb 10, 2014
    Posts:
    43
    Ahh, many thanks!

    edit: also i dont think i can catch this exception, normally if there is an exception it would say what kind of exception.. I've tried most of them and none seem to catch it, but oh well.. if i build the server and it happens it doesnt pause the server, only in the editor it pauses.