Hello all, I have spent the last week trying to get a variable to sync on the server and the client side for my project. I am implementing a character selection system where users can create a character and then select it for a game. All of the characters are saved to a file and they all load perfectly. However, when the game tries to select a user, it simply does not work. The only time it works is if the user is the host. If a host selects a character, it selects it for him but the clients don't receive that update. When clients select a character, the selected character defaults to the default constructor for the Character class. Say we have a character list that has 4 different characters on it. If the host tries to select one of these character, it will work for him but all of the clients will not know about it and won't update. If a client has a different list of 5 characters and tries to select one, he cannot; even if the character is perfectly valid, it will default to the default Character constructor for some reason. I am invoking a method called CmdSelectCharacter. When a client passes in a perfectly fine Character, somehow it defaults to the default constructor of the Character class. Take a look at some code below: Code (CSharp): [SyncVar(hook = "OnCharacterChange")] private Character _currentCharacter = null; public override void OnStartLocalPlayer() { base.OnStartLocalPlayer(); //Set the default character if(isServer) { CmdSetCharacter(_characterList[0]); } else { CmdSetCharacter(_characterList[1]); } } private void OnCharacterChange(Character character) { Debug.LogError("Selecting character: " + character.Name); } [Command] private void CmdSetCharacter(Character character) { _currentCharacter = character; } And here is the Character class Code (CSharp): [System.Serializable] public class Character { public string Name = ""; public Sprite Portrait = null; public GameObject Prefab = null; //Constructors public Character() { Name = "Character"; Portrait = null; Prefab = null; } public Character(string name, Sprite portrait, GameObject prefab) { Name = name; Portrait = portrait; Prefab = prefab; } } As you see under the OnStartLocalPlayer method, the server and client are trying to select two different characters, but for some reason, the host is the only one that selects normally! When a client joins a game, it justs selects the default constructor of Characters, even though _characterList[1] is a character named "Kyle." Does anybody have any idea as to why the [SyncVar] command is not working properly here? If I need to explain further, please let me know!
From the doc https://docs.unity3d.com/ScriptReference/Networking.SyncVarAttribute.html Best bet is to either have a list of characters and send the selected index or create a struct and send all the information about the character and reconstruct on each client.
Lmao, I cannot believe I missed that. I even checked out that link before lol. I cannot do the first option you mentioned because I already tried that and since every single player will have a different character list, it would not work. I am interested in the second option though. How would I go about doing that? I have already converted my Character class to a struct but I am not entirely sure how I would just "send" that character data to every client when a character is changed. Sorry about this, but I am sooo inexperienced with networking lol.
Have a look at the section of the manual that talks about Commands and ClientRPCs. This allows you to execute methods on the host and connected clients. When a client changes something in their character they can send a Command to the host telling them about their change. The Command can turn around and send a ClientRPC to all clients (including the one who sent the Command) telling them that a player changed something. The ClientRPC can then process the changes in the game world (or delegate out to whatever needs to do those changes).