Search Unity

[Command] between 2 different scripts

Discussion in 'Multiplayer' started by Royall, Jun 20, 2015.

  1. Royall

    Royall

    Joined:
    Jun 15, 2013
    Posts:
    121
    I am trying to learn how to use remote actions: http://docs.unity3d.com/Manual/UNetActions.html
    Problem is all the examples have sending part in the same class as the receiving part.

    In my case I have a ClientController and a ServerController. The servercontroller script is only runned by the server and the clientcontroller by the clients.

    Now let's say I want to send a login request sending a username:

    Client (ClientController.cs):
    Code (CSharp):
    1. userName = GUI.TextField(new Rect(10, 10, 200, 20), userName, 25);
    2.             if(GUI.Button(new Rect(10, 40, 120, 30), "Login")) {
    3.                 CmdLogin(userName);
    4.             }
    Server (ServerController.cs):
    Code (CSharp):
    1.     [Command]
    2.     void CmdLogin(string userName) {
    3.         Debug.Log(userName);
    4.     }
    Because the command is in a different class it gives the following error: error CS0103: The name `CmdLogin' does not exist in the current context

    Problem is I also can't reference to the function because the ServerController script doesnt run on clients...

    How do I fix this?
     
  2. Carpe-Denius

    Carpe-Denius

    Joined:
    May 17, 2013
    Posts:
    842
    Commands have to be on the same behaviour of the same object, so you have to put your methods on your player. In your simple case you can just move the method from ServerController to ClientController, since the clientcontroller is probably your player object and thus on the server, too.
     
  3. Royall

    Royall

    Joined:
    Jun 15, 2013
    Posts:
    121
    Then how can I make main controllers for both the client and server handeling more general stuff?
    I am looking for a function like the RPC's from the old networking engine. Every object could send them...

    What about if you have a Server in a complete different Unity project? Can't understand the logic...
     
  4. Carpe-Denius

    Carpe-Denius

    Joined:
    May 17, 2013
    Posts:
    842
    Send a message if you want to. Commands make object syncronization very simple and work only on its own object.
    If you want to send something to a central server object, just register a messagehandler.

    http://docs.unity3d.com/Manual/UNetMessages.html
     
  5. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    The networking HLAPI has a security model for commands from clients. Only the player object for a connection can use commands. If you want to work outside that security model for client-to-server communication you can use network messages - like in the MasterServer example project.
     
  6. Royall

    Royall

    Joined:
    Jun 15, 2013
    Posts:
    121
    Only the player object?
    I think it's kinda weird if the player object sends a login request from the menu?
     
  7. Carpe-Denius

    Carpe-Denius

    Joined:
    May 17, 2013
    Posts:
    842
    That's why you can use messages across everything.

    On the server:
    Code (csharp):
    1.  
    2. void Start(){
    3. NetworkServer.RegisterHandler(1000, OnLoginRequest); // 1000 -> your own short message type
    4. }
    5. void OnLoginRequest(NetworkMessage msg){
    6. Debug.Log(msg.ReadMessage<StringMessage>().value);
    7. }
    8.  
    Client:
    Code (csharp):
    1.  
    2. void Whenever(){
    3. NetworkClient.Send(1000, new StringMessage("Peter"));
    4. }
    5.  
     
  8. Royall

    Royall

    Joined:
    Jun 15, 2013
    Posts:
    121
    And what if I want to add more arguments? Like RPC's?
     
  9. Carpe-Denius

    Carpe-Denius

    Joined:
    May 17, 2013
    Posts:
    842
    You can write your own message types. Or you can send it to your playerobject and after that to your server:

    Code (csharp):
    1.  
    2. public class MyPlayer : NetworkBehaviour{
    3. [Command]
    4. void CmdLoginMessage(string name, string passwordHash){
    5.     MyServerObject.Login(name, passwordHash);
    6.   }
    7.  
    8. void YourLoginMethod(){
    9.     CmdLoginMessage("Peter", "23425ff");
    10.   }
    11. }
    12.  
    Since commands are only possible on your own playerobjects, you can always use "connectionToClient" to determine which client sent the data, e.g. MyServerObject.Login(connectionToClient, name, passwordHash);
     
  10. Royall

    Royall

    Joined:
    Jun 15, 2013
    Posts:
    121
    Thanks for the help guys, I figured out how to send messages :D