Search Unity

Unity Multiplayer Suggestion: GlobalRpc, ObserverRpc, TargetRpc

Discussion in 'Connected Games' started by vis2k, Jan 28, 2016.

  1. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,242
    • Rename ClientRpc to something like ObserverRpc. I just found out that ClientRpc only calls the Rpc for the client's observers, not for all clients (it says 'all clients' in the documentation, that's very misleading).
    • Add something like GlobalRpc: calls the Rpc on ALL clients. Right now we have to iterate through NetworkServer.objects and send a Message to all of them. This is just a lot of work for something that should be simple.
    • Add something like TargetRpc: calls the Rpc on just ONE client. seanr mentioned somewhere that this will be part of 5.4, so that's good. Right now we still have to use a Message, which is a lot of work for something that should be simple.
     
    Last edited: Jan 31, 2016
    DshFox, wwm0nkey, Chom1czek and 5 others like this.
  2. syleron

    syleron

    Joined:
    Mar 6, 2009
    Posts:
    3
    +1 The documentation is misleading and would like what Vis2k considered.
     
    Leoo and vis2k like this.
  3. Leoo

    Leoo

    Joined:
    May 13, 2013
    Posts:
    96
    Bump dis like there is no tomorrow.
     
    vis2k likes this.
  4. Krambolage

    Krambolage

    Joined:
    Jan 22, 2013
    Posts:
    17
    +1 that'd be a good thingimho
     
    vis2k likes this.
  5. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,242
    I can't find the source anymore, but as mentioned above: seanr said that TargetRpc will be in 5.4, but there is nothing in the release notes.
    Pro users can already test 5.4: https://unity3d.com/unity/beta , can any Pro user confirm that it contains TargetRpc? Or any word on this from @seanr perhaps?
     
  6. wwm0nkey

    wwm0nkey

    Joined:
    Jul 7, 2015
    Posts:
    33
    GlobalRpc would be glorious
     
    vis2k likes this.
  7. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    966
    If renaming class names would be so easy to do, I would also be grateful.

    I am pretty sure there's a reason why it's named after ClientRpc, ServerRpc, and so on, and it has to do with the name reflecting upon the tech framework behind the scenes. But I don't know.

    If you do a poll, maybe it will tell a different side of the story?
     
  8. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,242
    There is no ServerRpc as far as I know. Rpc always means 'call this on the client' in UNET. Functions that should be called on the server are Commands ala CmdMyFunction.

    So as long as it ends with 'Rpc', it's probably clear enough that it's for the client.
     
  9. Orami

    Orami

    Joined:
    Mar 12, 2015
    Posts:
    17
    I really need that send to one client RPC it would make my life so much easier right now I am thinking about adding a "owner" string to all clients and if the client's name is not "owner" then it disregards the information, but that is so much wasted overhead it isn't even funny. I guess Unet is still very young in it's inception - I even thought ClientRPC sent to all clients any other odd things you all have seen?
     
  10. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,242
    I think TargetRPC is in Unity 5.4 already.
     
  11. Orami

    Orami

    Joined:
    Mar 12, 2015
    Posts:
    17
    [TargetRPC] doesn't seem to exist within UnityEngine.Networking in 5.3.5f1
    I just tried to type it in and it was no go there is a [GUITarget] though....
    I've learned my lesson about upgrading to new builds of unity when working on something. lol I'll load it on the laptop maybe and see.
     
  12. nsmith1024

    nsmith1024

    Joined:
    Mar 18, 2014
    Posts:
    642
    I attached a class based on NetworkBehariour at run time (gameObject.addComponent<NetworkBehaviourClass>()) but when i do, it never receives ClientRpc calls. Anybody know anything about that?
     
  13. J_Troher

    J_Troher

    Joined:
    Dec 2, 2013
    Posts:
    41
    Does anyone here know how to use the message base? I've looked at the doc and stuff and faint tutorials but I just don't get it.. What I need to do doesn't seem that complex to me :/
     
  14. Apparaten_

    Apparaten_

    Joined:
    Jul 9, 2013
    Posts:
    44
    I'm using 5.4b23, ClientRpc seems to send to all clients, but i want to send to all clients except the owner.

    Right now im just ignoring the message by
    If(IsLocalPlayer)
    return;

    But its such a waste to send to a target that doesnt need it...

    Am i missing something here?
     
  15. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    289
    I also thought that something like this might be a nice addition so I had created this feature request.
     
    Apparaten_ likes this.
  16. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,242
    TargetRpc was finally implemented in the latest versions, it works fine
     
  17. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    289
    Yes, but this is not about TargetRPC. It is about RPC to all but one, like an inverted TargetRPC.

    For example, if the server has received data from one client and then needs to redistribute it, it might not always be necessary to send this data back to the client who originally send it. So, this client could be excluded from the ClientRPC and some bandwidth could be saved. Currently, this option seems to be missing in the HLAPI.
     
    Last edited: Dec 1, 2016
  18. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    3,242
    Oh okay, sorry
     
  19. Zephilinox

    Zephilinox

    Joined:
    Sep 15, 2014
    Posts:
    14
    This is how I've done it, it took a while to figure out how to get all the relevant connection ID's.

    The only downside is that with target RPC's you're forced to send the client the NetworkConnection data, so if that data is more expensive than simply sending the client redundant information there's no point worrying about it. I'm not sure how to find out the size of the connection data, but I assume it's on the larger end (40 bytes?, plus whatever unet does to optimise it), multiplied by the number of clients that don't own it.

    In other words it's only worth it for really large data unless you only have 2 or 3 clients.

    Code (CSharp):
    1.     [Command]
    2.     void CmdUpdatePosition(string serializedPositions)
    3.     {
    4.         //We the server have now been informed of these positions so now just inform all the clients about them
    5.         for (int i = 0; i < NetworkServer.connections.Count; ++i)
    6.         {
    7.             //If it's null then the client disconnected
    8.             if (NetworkServer.connections[i] == null)
    9.             {
    10.                 Debug.Log("Skipping disconnected");
    11.                 continue;
    12.             }
    13.  
    14.             //Don't call the Rpc on ourselves in case we are hosting
    15.             //Untested on server-only instance. Will this always be 0?
    16.             if (NetworkServer.connections[i].connectionId == NetworkManager.singleton.client.connection.connectionId)
    17.             {
    18.                 Debug.Log("Skipping self id " + NetworkManager.singleton.client.connection.connectionId);
    19.                 continue;
    20.             }
    21.  
    22.             //We don't need to tell the owner of the object the positions it just sent us
    23.             if (NetworkServer.connections[i].connectionId == GetComponent<NetworkIdentity>().clientAuthorityOwner.connectionId)
    24.             {
    25.                 Debug.Log("Skipping owner client id " + NetworkServer.connections[i].connectionId + " for " + gameObject.name);
    26.                 continue;
    27.             }
    28.  
    29.             TargetUpdatePosition(NetworkServer.connections[i], serializedPositions);
    30.         }
    31.  
    32.         //We also need them in case we are hosting, plus that way we know how many we received from the client
    33.         DeserializePositions(serializedPositions, ref networkPositions);
    34.         //Debug.Log("Received & Forwarding clients " + networkPositions.Count + " positions from " + gameObject.name);
    35.     }
    36.  
    37.     [TargetRpc]
    38.     void TargetUpdatePosition(NetworkConnection target, string serializedPositions)
    39.     {
    40.         if (!hasAuthority)
    41.         {
    42.             DeserializePositions(serializedPositions, ref networkPositions);
    43.         }
    44.         else
    45.         {
    46.             Debug.LogError("Received position update from server even though we own this object");
    47.         }
    48.     }
     
    Last edited: Dec 2, 2016