Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Assigning names to players

Discussion in 'Editor & General Support' started by SeanTheDeveloper, Aug 7, 2021.

  1. SeanTheDeveloper

    SeanTheDeveloper

    Joined:
    Aug 2, 2020
    Posts:
    25
    Hello, I have been following a tutorial by Dapper Dino about player names (
    )

    The issue is that the only name that was enabled was the host's. I have also discovered that the second player name doesn't exist, the text value of the input field is nothing.

    Here is my code:

    UIManager
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using MLAPI;
    6. using System.Text;
    7. using UnityEngine.UI;
    8. using System;
    9.  
    10. public class UIManager : MonoBehaviour
    11. {
    12.     [SerializeField] private InputField passwordInputField;
    13.     [SerializeField] private InputField nameInputField;
    14.     [SerializeField] private GameObject passwordUI;
    15.     [SerializeField] private GameObject leaveButton;
    16.  
    17.     private static Dictionary<ulong, PlayerData> clientData;
    18.  
    19.     private void Start()
    20.     {
    21.         NetworkManager.Singleton.OnServerStarted += HandleSeverStarted;
    22.         NetworkManager.Singleton.OnClientConnectedCallback += HandleClientConnected;
    23.         NetworkManager.Singleton.OnClientDisconnectCallback += HandleClientDisconnected;
    24.  
    25.         passwordUI.SetActive(true);
    26.         leaveButton.SetActive(false);
    27.     }
    28.  
    29.     private void OnDestroy()
    30.     {
    31.         if (NetworkManager.Singleton == null) { return; }
    32.  
    33.         NetworkManager.Singleton.OnServerStarted -= HandleSeverStarted;
    34.         NetworkManager.Singleton.OnClientConnectedCallback -= HandleClientConnected;
    35.         NetworkManager.Singleton.OnClientDisconnectCallback -= HandleClientDisconnected;
    36.     }
    37.  
    38.     private void HandleClientConnected(ulong clientId)
    39.     {
    40.         if (clientId == NetworkManager.Singleton.LocalClientId)
    41.         {
    42.             passwordUI.SetActive(false);
    43.             leaveButton.SetActive(true);
    44.         }
    45.     }
    46.  
    47.     private void HandleClientDisconnected(ulong clientId)
    48.     {
    49.         if (NetworkManager.Singleton.IsServer)
    50.         {
    51.             clientData.Remove(clientId);
    52.         }
    53.  
    54.         if (clientId == NetworkManager.Singleton.LocalClientId)
    55.         {
    56.             passwordUI.SetActive(true);
    57.             leaveButton.SetActive(false);
    58.         }
    59.     }
    60.  
    61.     public void Leave()
    62.     {
    63.         if (NetworkManager.Singleton.IsHost)
    64.         {
    65.             NetworkManager.Singleton.StopHost();
    66.         }
    67.  
    68.         else if (NetworkManager.Singleton.IsClient)
    69.         {
    70.             NetworkManager.Singleton.StopClient();
    71.         }
    72.  
    73.         passwordUI.SetActive(true);
    74.         leaveButton.SetActive(false);
    75.     }
    76.  
    77.     public static PlayerData? GetPlayerData(ulong clientId)
    78.     {
    79.         if (clientData.TryGetValue(clientId, out PlayerData playerData))
    80.         {
    81.             return playerData;
    82.         }
    83.  
    84.         return null;
    85.     }
    86.  
    87.     private void HandleSeverStarted()
    88.     {
    89.         if (NetworkManager.Singleton.IsHost)
    90.         {
    91.             HandleClientConnected(NetworkManager.Singleton.LocalClientId);
    92.         }
    93.     }
    94.  
    95.     public void Host()
    96.     {
    97.         clientData = new Dictionary<ulong, PlayerData>();
    98.         clientData[NetworkManager.Singleton.LocalClientId] = new PlayerData(nameInputField.text);
    99.  
    100.         NetworkManager.Singleton.ConnectionApprovalCallback += ApprovalCheck;
    101.         NetworkManager.Singleton.StartHost(new Vector3(-2f, 0f, 0f), Quaternion.Euler(-2f, 0f, 0f));
    102.     }
    103.  
    104.     public void Client()
    105.     {
    106.         var payload = JsonUtility.ToJson(new ConnectionPayload()
    107.         {
    108.             password = passwordInputField.text,
    109.             playerName = nameInputField.text
    110.         });
    111.  
    112.         byte[] payloadBytes = Encoding.ASCII.GetBytes(payload);
    113.  
    114.         NetworkManager.Singleton.NetworkConfig.ConnectionData = payloadBytes;
    115.         NetworkManager.Singleton.StartClient();
    116.     }
    117.  
    118.     private void ApprovalCheck(byte[] connnectionData, ulong clientID, NetworkManager.ConnectionApprovedDelegate callback)
    119.     {
    120.         string payload = Encoding.ASCII.GetString(connnectionData);
    121.         var connectionPayload = JsonUtility.FromJson<ConnectionPayload>(payload);
    122.         bool approveConnection = connectionPayload.password == passwordInputField.text;
    123.         Vector3 spawnPos = Vector3.zero;
    124.         Quaternion spawnRot = Quaternion.identity;
    125.  
    126.         if (approveConnection)
    127.         {
    128.             switch (NetworkManager.Singleton.ConnectedClients.Count)
    129.             {
    130.                 case 1:
    131.                     spawnPos = new Vector3(0f, 0f, 0f);
    132.                     break;
    133.                 case 2:
    134.                     spawnPos = new Vector3(2f, 0f, 0f);
    135.                     break;
    136.                 case 3:
    137.                     spawnPos = new Vector3(4f, 0f, 0f);
    138.                     break;
    139.             }
    140.  
    141.             clientData[clientID] = new PlayerData(connectionPayload.playerName);
    142.         }
    143.        
    144.         callback(true, null, approveConnection, spawnPos, spawnRot);
    145.     }
    146. }
    PlayerData
    Code (CSharp):
    1. public struct PlayerData
    2. {
    3.     public string PlayerName { get; private set; }
    4.  
    5.     public PlayerData(string playerName)
    6.     {
    7.         PlayerName = playerName;
    8.     }
    9. }
    PlayerText
    Code (CSharp):
    1. using UnityEngine;
    2. using MLAPI;
    3. using MLAPI.Messaging;
    4. using MLAPI.NetworkVariable;
    5. using UnityEngine.UI;
    6.  
    7. public class PlayerText : NetworkBehaviour
    8. {
    9.     [SerializeField] private Text displayNameText;
    10.  
    11.     private NetworkVariableString displayName = new NetworkVariableString();
    12.  
    13.     public override void NetworkStart()
    14.     {
    15.         if (!IsServer) { return; }
    16.  
    17.         PlayerData? playerData = UIManager.GetPlayerData(OwnerClientId);
    18.  
    19.         if (playerData.HasValue)
    20.         {
    21.             displayName.Value = playerData.Value.PlayerName;
    22.         }
    23.     }
    24.  
    25.     private void OnEnable()
    26.     {
    27.         displayName.OnValueChanged += HandleNameChanged;
    28.     }
    29.  
    30.     private void OnDisable()
    31.     {
    32.         displayName.OnValueChanged -= HandleNameChanged;
    33.     }
    34.  
    35.     private void HandleNameChanged(string oldDisplayName, string newDisplayName)
    36.     {
    37.         if (!IsClient) { return; }
    38.  
    39.         displayNameText.text = newDisplayName;
    40.     }
    41. }
    Thanks,
    Sean.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,946
    To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494
     
  3. SeanTheDeveloper

    SeanTheDeveloper

    Joined:
    Aug 2, 2020
    Posts:
    25
    The code seems to run fine. I have checked it with Debug.Log()

    Again, the client name value isn't shown. You should check out the link at the top.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,946
    You say that... and yet you also say...:

    Does not sound like "run fine" to me.

    I am not going to do the tutorial to find out where you made a mistake, or where the tutorial-maker made a mistake.

    I am offering you the same tools and processes that I bring to ALL engineering problems I encounter.
     
  5. SeanTheDeveloper

    SeanTheDeveloper

    Joined:
    Aug 2, 2020
    Posts:
    25
    So you tell me to start coroutines?
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,946
    I'm talking about putting Debug.Log() statements into the code to give you insight into how it runs.

    That has nothing to do with coroutines.
     
  7. SeanTheDeveloper

    SeanTheDeveloper

    Joined:
    Aug 2, 2020
    Posts:
    25
    But I did, and no errors were found
     
  8. SeanTheDeveloper

    SeanTheDeveloper

    Joined:
    Aug 2, 2020
    Posts:
    25
    I did get this error when I removed the (!IsServer) { return; } :
    NullReferenceException: Object reference not set to an instance of an object
    UIManager.GetPlayerData (System.UInt64 clientId) (at Assets/UIManager.cs:78)

    Line 78 in UIManager is: if (clientData.TryGetValue(clientId, out PlayerData playerData))