Search Unity

simple setup issues... ClientRpc problems

Discussion in 'Multiplayer' started by ryleigh, Jul 22, 2015.

  1. ryleigh

    ryleigh

    Joined:
    Nov 9, 2010
    Posts:
    6
    I'm having trouble starting a turn-based game.

    I'd like to create some object that only exists on the server and keeps track of game state, e.g. whose turn it is. I want each client to be able to send messages to this object, and for it to be able to send messages to all clients.

    Sending Commands from the Players works, but sending ClientRpcs to all clients is a big source of confusion for me. I'm able to successfully send them when I call them from a Command in the Player script, but I can't figure out how to send them from an object that exists only on the server.

    Simply having a ServerGameController script on a gameobject in the scene and checking ServerOnly on its NetworkIdentity doesn't seem to be enough - I believe because scripts must have been "spawned" to be able to send ClientRpcs.

    So now I'm trying to figure out at what point (and from which other script) would be best to spawn my serverside game-state controller object, and everything already feels very messy and like I'm overcomplicating things.

    If anyone knows a simple way to accomplish what I'm trying to do (have one server-side script that can receive Commands from both client Player scripts, and send ClientRpcs to both client Player scripts), or a better way to handle things if I'm going about it all wrong, help would be appreciated.
     
  2. _Adriaan

    _Adriaan

    Joined:
    Nov 12, 2009
    Posts:
    481
    Why not spawn an object on both the server and client (using network instantiating) but only allow the server to run the game code?
     
  3. ryleigh

    ryleigh

    Joined:
    Nov 9, 2010
    Posts:
    6
    As far as I understand it, when 2 players are connected and one is the host, there's 2 clients and 1 server in the mix. If I spawn an object to control game state, won't a copy exist on the server and on each of the clients?

    I guess I'm too hung up on having the canonical game state ONLY existing on the server (and the server just telling each client when it's their turn, etc)... but maybe having the game state be synced to all clients as well is a better approach. I think that's what you're suggesting, at least.
     
  4. _Adriaan

    _Adriaan

    Joined:
    Nov 12, 2009
    Posts:
    481
    As an (untested) example, if you've spawned an object with the following script, the code that can set the player turn will only run on the server:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Networking;
    3. using System.Collections;
    4.  
    5. public class GameController : NetworkBehaviour
    6. {
    7.     int thisPlayer = 2;
    8.  
    9.     [SyncVar]
    10.     int playerTurn = 1;
    11.  
    12.     void Update ()
    13.     {
    14.         if(isLocalPlayer && Time.time > 15f)
    15.         {
    16.             //only executed on local player client, executed (every frame; oops) after 15 seconds
    17.             CmdTellServerIveHadMyTurn();
    18.         }
    19.     }
    20.  
    21.     [Command]
    22.     void CmdTellServerIveHadMyTurn()
    23.     {
    24.         //only executed on server
    25.         playerTurn++;
    26.         RpcNotifyClients(playerTurn);
    27.     }
    28.  
    29.     [ClientRpc]
    30.     void RpcNotifyClients(int turn)
    31.     {
    32.         if(thisPlayer == turn)
    33.         {
    34.             //my turn!
    35.         }
    36.         else
    37.         {
    38.             //not my turn!
    39.         }
    40.     }
    41. }
    Does that help? :)
     
  5. ryleigh

    ryleigh

    Joined:
    Nov 9, 2010
    Posts:
    6
    Thanks a lot man! I'm testing it out right now and it does feel quite nice and simple.
    Couple more questions though if you don't mind:

    Right now I'm just treating this GameController object as my player prefab on the NetworkManager. Would you recommend spawning it from somewhere else, and where if so? Should I be subclassing NetworkManager and spawning some stuff there when the server is set up?

    And I'm unsure about the best way to assign player 1 the id=1, and player 2 id=2 without doing something hacky.
     
  6. _Adriaan

    _Adriaan

    Joined:
    Nov 12, 2009
    Posts:
    481
    I'm very much a beginner too, but yeah, you could look into subclassing NetworkManager to replace the virtual functions you need, giving it your own implementation. Here's what you can override.