Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by vladtehnik · Nov 09, 2019 at 09:12 PM · networkingcharacterswitch

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.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

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.

SyncVars

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

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image vladtehnik · Nov 08, 2019 at 02:42 PM 0
Share

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.

avatar image AconitumNapellum vladtehnik · Nov 08, 2019 at 04:01 PM 0
Share

Lol, I made a typo. On the syncvar, change the line

 [SyncVar(hook = "OnCharacterChanged")]

To

 [SyncVar(hook = "OnChangeCharacter")]

avatar image vladtehnik AconitumNapellum · Nov 11, 2019 at 01:04 PM 0
Share

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.

avatar image vladtehnik · Nov 11, 2019 at 03:01 PM 0
Share

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

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

205 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

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

Access other gameObject's components in C# script 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges