- Home /
Unity Networking Problem
Hello ! I am currently making a networked game in which I need a player character changer. I have placed two buttons that let you switch between characters (boy and girl) and then when you connect to the server you are supposed to spawn with your character visible to other clients. Here is where i need help.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class ChangeCharacter : NetworkBehaviour
{
public bool Boy;
public GameObject GM;
public GameObject BM;
public void Guy()
{
Boy = true;
}
public void Girl()
{
Boy = false;
}
[ClientRpc]
public void RpcOnCharacterChanged(bool Boy1)
{
Boy = Boy1;
if (!isLocalPlayer)
{
return;
}
if (Boy1) {
BM.SetActive(true);
GM.SetActive(false);
}
else
if (!Boy1)
{
BM.SetActive(false);
GM.SetActive(true);
}
}
[Command]
void CmdTellServerMyCharacter(bool Boy1)
{
RpcOnCharacterChanged(Boy1);
}
public override void OnStartLocalPlayer()
{
CmdTellServerMyCharacter(Boy);
}
}
The client can see the change that he made, can see whether the host has a character different that his, but the host can't see the client's character. The same applies with a client joined later than another clent. I don't understand where I went wrong.
Answer by AconitumNapellum · Nov 08, 2019 at 02:07 PM
Don't worry, everyone who's been trying to code a networked game has been through this hell, you're not alone :D.
What is happening is that when the host player gets instantiated in a client that connects after the game has already started, the host player gameobject doesn't really know if he's a boy or a girl, because he's been instantiated by the player. It's not easy to understand, so i modified your code a bit:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class ChangeCharacter : NetworkBehaviour
{
[SyncVar(hook = "OnCharacterChanged")]
public string character;
public GameObject GM;
public GameObject BM;
public void Guy()
{
character = "boy";
}
public void Girl()
{
character = "girl";
}
[ClientRpc]
public void RpcOnCharacterChanged(string newcharacter)
{
character = newcharacter;
if (!isLocalPlayer)
{
return;
}
DetermineCharacter();
}
[Command]
void CmdTellServerMyCharacter(string newcharacter)
{
RpcOnCharacterChanged(newcharacter);
}
public override void OnStartLocalPlayer()
{
CmdTellServerMyCharacter(character);
}
void OnChangeCharacter(string newValue)
{
character = newValue;
DetermineCharacter();
}
void DetermineCharacter()
{
if (character == "boy")
{
BM.SetActive(true);
GM.SetActive(false);
}
else
{
BM.SetActive(false);
GM.SetActive(true);
}
}
}
Notice i'm now using a string syncvar instead of a boolean.
The syncvar stays up to date with its copy on the server, and has an hook function that fires when it changes. In this function you should update the local variable with the newValue that the server gives you, and then change the local character to resemble the correspon ding one on the server.
The code should work, try it and tell me if you got any more issues
Thanks for your help, but I get this error: UNetWeaver error: SyncVar Hook function OnCharacterChanged not found for ChangeCharacter UnityEngine.Debug:LogError(Object)
and Failure generating network code. UnityEditor.Scripting.ScriptCompilation.EditorCompilationInterface:TickCompilationPipeline(EditorScriptCompilationOptions, BuildTargetGroup, BuildTarget)
. What should I do ? I have tried changing the hook to RpcOnCharacterChanged ins$$anonymous$$d of OnCharacterChanged, but the character the host has chosen applies for all of the clients. I think the string on the host applies for all of the clients because of the syncvar, but II don't think it would work without a syncvar with a hook.
Lol, I made a typo. On the syncvar, change the line
[SyncVar(hook = "OnCharacterChanged")]
To
[SyncVar(hook = "OnChangeCharacter")]
It still does not work properly ?? Let's say the host is a girl, client1 is a boy and client 2 is a girl. host sees himself as a girl, client1 sees himself as a girl but sees the host and the client2 as boys and client2 sees everyone as males. This is a very wierd situation..
Also, the character is changed before joining/creating the server, in the "main menu", on the player prefab. I don't think this is the best approach and I think this might be a cause for such a wierd behaviour.
I got it working, but it does not update for new players that join. I made some new modifications, you can now change you character once you join a server and can do as many times as you want. Also, the "character" string is directly changed from the buttons OnClick() function so I don't need the Boy() and Girl() functions but when a new client joins in and for example the host changed his character before the client joined, the client can't see the change. Why does not the SyncVar work ? Is it possible that I may have changed something in order for this to happen ??
Here is the final script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class ChangeCharacter : NetworkBehaviour
{
[SyncVar(hook = "OnChangeCharacter")]
public string character;
public GameObject G$$anonymous$$;
public GameObject B$$anonymous$$;
public GameObject GUI;
public void Start()
{
character = "boy";
}
[ClientRpc]
public void RpcOnCharacterChanged(string newcharacter)
{
character = newcharacter;
if (!isLocalPlayer)
{
return;
}
Deter$$anonymous$$eCharacter();
}
[Command]
void CmdTellServer$$anonymous$$yCharacter(string newcharacter)
{
RpcOnCharacterChanged(newcharacter);
}
public void OnClickButton()
{
CmdTellServer$$anonymous$$yCharacter(character);
}
void OnChangeCharacter(string newValue)
{
character = newValue;
Deter$$anonymous$$eCharacter();
}
void Deter$$anonymous$$eCharacter()
{
if (character == "boy")
{
B$$anonymous$$.SetActive(true);
G$$anonymous$$.SetActive(false);
}
else
if (character == "girl")
{
B$$anonymous$$.SetActive(false);
G$$anonymous$$.SetActive(true);
}
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220612214525im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Instantiate a prefab and switch character control to it 0 Answers
character switching problem 1 Answer
switch character 1 Answer
switching between in game characters 2 Answers