1

I have a scene where the player has the option to choose settings for the match they are creating (number of rounds, time per round etc..), I also have a utility class MatchSettings that contains all of these settings, when I run the game on the host everything works fine, however when a client joins the game, the clients match settings are 0 for everything, The settings are used as part of a GameManager class that implements a singleton pattern with a MatchSettings member. So my question is how can I have all the participants of the game share the same settings? ( I am aware that u-net is deprecated)

The Relevant Code for the GameManager:

public class GameManager : MonoBehaviour
{
    public static GameManager instance;
    public MatchSettings settings;
    void Awake()
    {
        if(instance != null)
        {
            Debug.LogError("Too many game managers");
        }
        else
        {
            instance = this;
            respawnCamera.SetActive(false);
            settings = new MatchSettings();
            timePassed = settings.roundTime * 60;
            roundsPlayed = 0;
            highestKills = 0;
        }
    }
     void Update()
     {
        timePassed -= Time.deltaTime;
        if (timePassed < 0 || highestKills >= settings.maxKills)
        {
            Debug.Log(settings.roundTime); //prints 0 at client runtime
            RoundOver();
        }
        if(roundsPlayed >= settings.roundCount)
        {
            GameOver();
        }
    }
}

The relevant code for the MatchSettings:

[System.Serializable]
public class MatchSettings
{

    public  float roundovertime = 10f;
    public static float roundtime; // the variables from the UI scene are stored in the static members and transferred
    public static int maxkills; // into the regular ones when MatchSettings() is called [in awake in game  manager]
    public static int roundcount;
    public float respawntime = 5f;
    public float roundTime;
    public int maxKills;
    public int roundCount;
    public MatchSettings()
    {
        roundTime = roundtime;
        maxKills = maxkills;
        roundCount = roundcount;
    }
}

Thanks in advance!

barbecu
  • 684
  • 10
  • 28

1 Answers1

0

Unless you synchronize MatchSettings to all clients, you will always have the default values there (zeros in this case).

One way about it using UNET is using SyncVar - You will need to have the settings on a gameobject in the scene, owned by the server which will be your "source of truth".

You only perform changes on the server side, and it will be automatically updated to all clients.

Pseudo-code example:

class GameSettings : NetworkBehaviour {
 [SyncVar(hook=nameof(FragsRequiredAmountSyncVarChanged))] private int _fragsRequiredToWinSyncVar = 20;

 public void ChangeFragsRequiredToWin(int newAmount) {
  if (!isServer) {
   Debug.LogError("Sync vars can only change on the server!");
   return;
  }
  _fragsRequiredToWinSyncVar = newAmount;
 }

 private void FragsRequiredAmountSyncVarChanged(int newAmount)
 {
  Debug.Log($"Frag requirement changed to {newAmount}");
 }
}

I've also included an example on how to attach hooks when the SyncVar changes; I'm pretty sure it gets called on both the server and the client, but my memory might fail me since it's been quite a while since I last used UNET.

Ron
  • 1,806
  • 3
  • 18
  • 31
  • as i understand it SyncVar can only serialize basic data types, and so then I would have to split up every setting and mark it as a syncvar, wouldnt that be performance heavy? – barbecu Feb 16 '20 at 13:43
  • Actually it's quite efficient; SyncVars only send updates – Ron Feb 16 '20 at 15:00
  • I see, would you be kind enough to provide an outline of what implementing it would look like? ( the server side changes and calling them) – barbecu Feb 16 '20 at 15:45
  • @barbecu added an example – Ron Feb 17 '20 at 10:13