Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Networking - RPC on the server

Discussion in 'Multiplayer' started by benblo, Nov 2, 2007.

  1. benblo

    benblo

    Joined:
    Aug 14, 2007
    Posts:
    476
    I'm building a list of the players connected on a host, with a button in front of each player to get extra info about them.
    So basically I need to do a round-trip: the client asks (via RPC) the info on player X, the server receives the RPC and sends back another one with said info, and finally the client receives the info he wanted.

    This all works... except on the host! When I make a RPC call with RPCMode.Server, it's just ignored.
    Is that expected behavior or bug?

    So a), I need to check on both end of the round-trip if Network.isServer, and use RPC or SendMessage accordingly. Messy.
    And b), I can't SendMessage with more than one argument (which I need to), so it's even messier, I have to implement a complete second logic. All this for one simple round-trip.

    Now why the hell can SendMessage only use one argument is beyond me, even RPC() is better at this game! I won't even mention Invoke, which takes no argument.
     
  2. larus

    larus

    Unity Technologies

    Joined:
    Oct 12, 2007
    Posts:
    277
    Code (csharp):
    1.  
    2. This all works... except on the host! When I make a RPC call with RPCMode.Server, it's just ignored.
    3. Is that expected behavior or bug?
    4.  
    RPCMode.Server only does a remote procedure call and not local execution. Thats the way its set up right now. To do what you want to do:

    Code (csharp):
    1.  
    2. networkView.RPC("SomeFunction", RPCMode.Server, parameter1, parameter2);
    3.  
    becomes

    Code (csharp):
    1.  
    2. if (Network.isServer)
    3.     SomeFunction(parameter1, parameter2);
    4. else
    5.     networkView.RPC("SomeFunction", RPCMode.Server, parameter1, parameter2);
    6.  
    If the function is in another object couldn't you reference that object directly instead of using SendMessage and thus avoid changing the target function? Like someObject.SomeFunction(etc, etc).
     
  3. benblo

    benblo

    Joined:
    Aug 14, 2007
    Posts:
    476
    Yes, my function is indeed in another object, that I can reference... in this case.
    But I wanted to point out that it's a pity to have to break the code model just to adapt for the case of the host, while it works for everyone else.
    Maybe you could make an overload of the RPC function for this "also send to myself" case...? Maybe it could even be a parameter of the [RPC] attribute.


    On a more general subject, I find it super-cool that RPC accepts more than one parameter, but it also reveals how sad it is that SendMessage doesn't.
    Is there any technical limitation to that? I really can't see why there would, since you can do it with RPC, so...


    Also, I tried to make overloads to keep the code closer to the original model, like:
    Code (csharp):
    1.     [RPC]
    2.     void SendPlayerInfo(NetworkPlayer requester, int playerID)
    3.     {
    4.         // this is sent via RPC
    5.     }
    6.     void SendPlayerInfo(int playerID)
    7.     {
    8.         // this is called directly via a reference
    9.     }
    10.  
    This way I can always use the same call model, or even make a helper that would automatically do something like:
    Code (csharp):
    1.     if (Network.isClient)
    2.         networkView.RPC("SendPlayerInfo", RPCMode.Server, Network.player, playerID);
    3.     else
    4.         SendMessage("SendPlayerInfo", playerID);
    5.  
    (I didn't work out everything yet but you get the idea.)

    ... but it doesn't work because I get a "wrong number of parameters" exception, for both RPC and SendMessage.
    So I suppose that they call the first available overload, without checking the parameter types.

    So I'm wondering, how do SendMessage and RPC work exactly? Are you using Reflection, or is it some sort of faster but more limited internal implementation?
    Because with Reflection I know how to find the correct overload depending on the parameters, and could, I think, implement some sort of more generic SendMessage, but I'm just worried it would be too slow to use... or would it?