Search Unity

Identifying instantiated players (Multiplayer) and using their player names from array?

Discussion in 'Scripting' started by Jeepster, Jan 21, 2020.

  1. Jeepster

    Jeepster

    Joined:
    Jan 23, 2014
    Posts:
    401
    Hi,

    In each scene, I've made this Game Manager script to check and list (in an array) how many and which players have spawned but so far I'm only checking how many:
    Code (CSharp):
    1. public class GameManagerDeaths : MonoBehaviour {
    2.  
    3. public GameObject[] instance;
    4.     public static string pseudo;
    5.  
    6.     void Start () {
    7.  
    8.         pseudo = globalVariables.pseudo;
    9.  
    10.  
    11.     }
    12.     void Update () {
    13.  
    14.         instance = GameObject.FindGameObjectsWithTag("Player");
    15.    
    16.  
    17.         foreach (GameObject go in instance)
    18.         {
    19.             go.name = pseudo;
    20.         }
    21. }
    22.  
    the "pseudo" is the name each player uses to sign in to the lobby before starting the match and they all have their own unique name which is carried into each scene.

    The array works and each player is listed but they all have the same pseudo/name because of the way I wrote it. My problem is that I'm not getting each players unique name: "pseudo" because I'm not identifying each player. I'm using "foreach" wrong...

    -How can I identify each players or in this cas "go" in the foreach statement and give them their respective pseudos?
     
  2. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    There are several things to take in consideration:
    - Do not (ever) use FindGameObjectsWithTag() in Update it alone will kill your performance, and better, do not use it whatsoever. Instead of polling for players gameobjects, try having players register themselves to your gamemanager when created.:
    Code (CSharp):
    1. public class GameManagerDeaths : MonoBehaviour
    2. {
    3.     static List<GameObject> Players = new List<GameObject>();
    4.  
    5.     public static void RegisterPlayer(GameObject playerGo)
    6.     {
    7.          Players.Add(playerGo);
    8.     }
    9.      
    10.     public static void UnregisterPlayer(GameObject playerGo)
    11.     {
    12.          Players.Remove(playerGo);
    13.     }
    14. }
    15.  
    16. public class Player : MonoBehaviour
    17. {
    18.     void OnEnable()
    19.     {
    20.          GameManagerDeaths.RegisterPlayer(this.gameObject);
    21.     }
    22.      
    23.      void OnDisable()
    24.     {
    25.          GameManagerDeaths.UnregisterPlayer(this.gameObject);
    26.     }
    27. }


    - How you sync names depends on what system you're using to connect players together. Dont think anyone can actually give you specific instructions without further information.
     
    Jeepster likes this.
  3. Jeepster

    Jeepster

    Joined:
    Jan 23, 2014
    Posts:
    401
    Thank you so much for your help. Your method to register the players works I think after debugging, but I cant get the list to be public in the inspector to check. But I'm sure it's a much better way to list all players without hurting performance.
    I'm using Photon Network for my game and I chose to leave out the entire lobby and instantiation code because it's a big bundle to look at, and could be more confusing than helpful.

    But from the code you posted, all I need (after making the list public) is to make sure that the names added to that list are the "pseudo" so something like this:

    Code (CSharp):
    1.   public static void RegisterPlayer(GameObject playerGo)
    2.     {
    3.          Players.Add(playerGo) + pseudo;
    4.     }
    This doesn't work, but I need to add the public static string "pseudo" to each game object that joins the list. Each object has a names script on them with the pseudo stored:
    Code (CSharp):
    1. [System.Serializable]
    2.  
    3. public class NamesScript : Photon.MonoBehaviour {
    4.  
    5.     public static string pseudo;
    6.     public int idForThisPlayer;
    7.     public GameObject canvasNames;
    8.  
    9.     public MPPlayerT m;
    10.    
    11.  
    12.     void Start()
    13.     {
    14.             idForThisPlayer = m.id;
    15.             pseudo = globalVariables.pseudo;
    16.             GetComponentInChildren<TMP_Text>().text = ""+ pseudo;
    17.             canvasNames.transform.Rotate(0, 180, 0);
    18.  
    19.     }
    20.  
    21.     // Update is called once per frame
    22.     void Update () {
    23.        
    24.     }
    25. }
    So I need to take their pseudo or names if you prefer and put them on the list. I hope it makes sense and thank you again for your help, I really appreciate it
     
  4. Jeepster

    Jeepster

    Joined:
    Jan 23, 2014
    Posts:
    401
    This one is probably closer to what I need, but it still doesn't work:
    Code (CSharp):
    1.     public static void RegisterPlayer(GameObject playerGo)
    2.     {
    3.         Players.Add(playerGo);
    4.         playerGo = playerGo.GetComponent<NamesScript>().pseudo;
    5.     }
    I'm trying to access the NamesScript and get the pseudo from there, but the error says : NamesScript.pseudo cannot be accessed with an instance and that it should be qualified with a type instead, but how can I qualify it with type and still get that specific gameobjects NamesScript to access the right pseudo?!