Search Unity

When is it "safe" to send my first client rpc/command

Discussion in 'Multiplayer' started by LukasO, Aug 8, 2015.

  1. LukasO

    LukasO

    Joined:
    May 23, 2013
    Posts:
    115
    Hi,

    I've noticed a bit of an inconsistency when trying to set up my game. When I start a new game, I want the server to set the necessary parameters and then send a message to clients (including the server itself) to show a screen. However at the moment I'm having to put a delay in, in order to make it work consistently. All functions below are in the same class which derives from a NetworkBehaviour.

    Code (CSharp):
    1.     public override void OnStartServer ()
    2.     {
    3.         if(LobbyManager.singleton.numPlayers == PlayerManager.instance.GetNumberOfPlayers())
    4.         {
    5.             StartServer();
    6.         }
    7.         base.OnStartServer ();
    8.     }
    9.  
    Server functions below:

    Code (CSharp):
    1.    
    2. [Server]
    3.     public void StartServer()
    4.     {
    5.         StartCoroutine (ServerNewGame ());
    6.     }
    7.  
    8.     [Server]
    9.     IEnumerator ServerNewGame()
    10.     {
    11.         yield return new WaitForSeconds (1f);
    12.         RelationshipInitializer.Instance.Initialize();
    13.         ChangeCampaign();
    14.     }
    15.  
    16.     [Server]
    17.     public void ChangeCampaign()
    18.     {
    19.         Campaign newCampaign = new Campaign();
    20.         RpcStartBudgetAllocation ();
    21.     }
    22.  
    ClientRPC function.

    Code (CSharp):
    1.     [ClientRpc]
    2.     public void RpcStartBudgetAllocation()
    3.     {
    4.         PickBudgetScreen.Instance.ShowScreen ();
    5.     }
    6.    
    I'm noticing however that without the delay in my ServerNewGame function, the RpcStartBudgetAllocation function is not called at all. Not on the client on the server or any other clients.

    Is there a particular reason why or a better way I should do this?
     
    Last edited: Aug 8, 2015
  2. Slight0

    Slight0

    Joined:
    Dec 6, 2013
    Posts:
    28
    It seems the the NetworkManager calls OnStartServer and OnStartHost before the hosts actually get started, in fact, there's currently no difference between the two functions really. (This may be a design flaw and may change) You're getting the issue because you're trying to call the RPC on a server instance that hasn't been initialized yet so nothing happens.

    I believe a decent workaround at the moment would be to use OnClientStart on the host machine like below.

    Code (CSharp):
    1. public override void OnStartClient(NetworkClient client)
    2. {
    3.     base.OnStartClient(client);
    4.     if (Network.isServer)
    5.     {
    6.         //Initialization that occurs right after server starts
    7.         StartServer();
    8.     }
    9. }
    Basically, OnStartClient is called right after the server is successfully started up on the server so it's your best bet at doing initialization right after the server gets setup.
     
  3. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,124
    well client connections should be ready to receive RPCs. in order to know when all clients are ready you should either iterate on all connections on NetworkServer and check if they are ready and then send the RPC or just send a ready command from each client to server (client's objects will be available after they are ready) and then gather all ready messages on server and then start after everyone is ready.

    the process is two phase
    first server gets initialized and all clients get connected
    then each clients signals the server that he/she is ready ClientScene.ReadyXXX (if you don't use network manager)
    after clients say they are ready all objects are spawned on them and RPCs can be received , before that only messages can be sent/received.