Unity networking Command-function not being called

Hi!

I’ve been making a multiplayer card game-thingy and have almost successfully managed to make the game work. Now I’m working on the end of the game and I’ve run into a problem that I just can’t figure out myself. The game ends when there are no more cards in a certain deck after which the clients and the server communicate. So here’s the problem itself: If the game ends when a client gets the last card of the deck (by clicking on it) all the clients and the server get the correct scores from each other, but when the server gets the last card only the server’s score gets passed around, no matter who actually wins. There are no errors, just nothing happening.


I have a network manager with a “game master”
prefab as player prefab and the deck
as a spawnable prefab. The prefabs have the network identity component, local player authority has no effect on the problem. The “game master” has a script “game” that handles all the networking stuff. I’ve done testing on unity editor and a standalone exe, using unity as both host and client. Below are all the relevant functions and some comments.

public class Game : NetworkBehaviour
{
    public Text scoretxt;
    public int[] pelaajienPisteet = new int[4];
    public int playerNumber = 0;


//This function gets called from a script in the deck. 
//This is the start
public void GameEnded()
    {
        CmdAnnounceEnd();
    }


//Now we're in the server and we'll tell all the clients that the game has ended
    [Command]
    void CmdAnnounceEnd()
    {
        RpcAnnounceEnd();
    }

//Now we're in the client and count the score
    [ClientRpc]
    void RpcAnnounceEnd()
    {
         //Manager has the network manager component
         //GetLocalPlayer returns the "game"-script of the local player
         //Player handles the actual game 
        int score= Manager.GetComponent<PlayerManager>
        ().GetLocalPlayer().players[0].GetComponent<Player>().CalculateScore();

        //This prints the correct score and playerNumber when unity editor is server and client
         print("Client's score " + score+ " " + Manager.GetComponent<PlayerManager>
        ().GetLocalPlayer().playerNumber);

        //This used to be Cmd but I changed it to see if calling a command from 
        //Rpc caused the problem
        SendScore(score, Manager.GetComponent<PlayerManager>().GetLocalPlayer().playerNumber);
    }

//This sends the score and playerNumber of each client's local player
    void SendScore(int score, int nmbr)
    {
        CmdSendScore(score, nmbr);
    }


//This is where I think the problems start
//In the SendScore function above I can print each client's own score, but it appears as if the 
   CmdSendScore function doesn't get called

//Now we're in the server and we should receive scores from players
    [Command]
    void CmdSendScore(int score, int nmbr)
    {
        //When a client gets the last card this prints the score of the player who sent it, and every client 
           sent their score
        //When the server gets the last card this prints only the server's score, only the server's score got 
           sent?
        print("Here's the score: " + score+ " " + nmbr);
        //Sends the clients this particular player's score
        RpcSendScore(score, nmbr);
    }

//Now we're in the client 
    [ClientRpc]
    void RpcSendScore(int score, int nmbr)
    {
        //Client last => prints everyone's score (not all at the same time)
        //Server last=> prints only server's score
        print(score+ " " + nmbr);

        Manager.GetComponent<PlayerManager>().GetLocalPlayer().DisplayScore(score, nmbr);
    }

//On the client, shows players' score in a text box
//Function needs improvement but it works
    public void DisplayScore(int score, int nmbr)
    {
        //Client last => prints everyone's score (not all at the same time)
        //Server last=> prints only server's score
        print("Player" + nmbr + " score: " + score);
        playerScores[nmbr - 1] = score; //Playernumbers start from 1
        scoretxt.enabled = true;
        string k = "";

        for (int i = 0; i < playerScores.Length; i++)
        {
            if (playerScores *!= 0)*

{
if (i == playerNumber - 1) k += "This is you: ";
k += "Player " + i + " score: " + playerScores + "
";

}
print(“score” + nmbr + " " + playerScores*);*
}
//Client last => Server and clients show all the scores correctly
//Server last=> Only server’s score shown on everyone
scoretxt.text = k;
}
}
Thanks for any help!

You have a strange setup here. First of all all relevant game data should be stored any managed by the server. Second “GameEnded” should be invoked by the server so there’s no need for a command. Commands are methods that are meant to be called by clients. Finally keep in mind that clients can only send commands to objects they have authority over. This is by default only the player object. I’m pretty sure your Game script is not attached to every player object, right? So it’s most likely located on a server owned object and therefore a player can’t send commands to that object.

Currently it looks like each client manages his own score. That means a client can simply tell the server it has 1000000 points. Most of the logic and bookkeeping of the game should happen on the server side where the server can vertify and validate everything. Using syncvars can really simplify some of the event and data flow.

It’s hart to give specific advice as we don’t know your setup, where which script is attached to and who owns which object(s).