Confused About UI Updates

Hi

I am an experienced programmer but new to Unity and I’m trying to figure out a problem I have with multiplayer and the display of information that is local to a client.

I am using the lobby from the Asset Store and I have got that part working without any real problems.

What I am trying to do is display the player name on the screen in a UI Text object. Obviously this would be different for each player and therefore client specific. What is confusing me is how I achieve this so I only have to update the control once.

Let me explain…

If I have a non multiplayer game I can make a once only update to the the UI as follows:

void Start () {
Text playerNameText = GameObject.Find(“Text”).GetComponent();
playerNameText.text = “Test Value”;
}

This works without a problem.

However when I have a multiplayer game this doesn’t seem to work. I have dramatically simplified the code to track down the problem but in the actual game I am passing the name from the lobby in a [SyncVar] which is working fine.

The thing is I have tried a number of different ways and the only one I can find to work and display the updated value is the following:

void Update () {
if (isLocalPlayer)
{
Text playerText = GameObject.Find(“PlayerNameText”).GetComponent();
playerText.text = “My Name”;
}
}

I have tried creating a class variable and putting the Find in the Start method and the OnStartLocalPlayer method but neither of them work.

While what I have works it strikes me as very inefficient a the value must be set every update. I have even tried tried putting in a check so it only sets the value once but that doesn’t work either.

I think I must be missing something fundamental in my understanding of how the networking implementation works.

Any help and advice welcome.

How about a coroutine? With some variation to stop it when you get the desired results.

IEnumerator Start () {
        if (isLocalPlayer) {
            while (GameObject.Find ("PlayerNameText").GetComponent<Text> () == null && playerText.text == "") {
                Text playerText = GameObject.Find ("PlayerNameText").GetComponent<Text> ();
                playerText.text = "My Name";
                yield return null;
            }
        }
    }

I couldn’t get that to work but you got me thinking in the right direction, this works and once it has successfully completed the flag stops it running more than once. The only thing I can think of is that there is come timing issue that stops it being set in the Start function.

    void Update()
    {
        if (isLocalPlayer)
        {
            if (!initialised)
            {
                playerTextObject = GameObject.Find("PlayerNameText").GetComponent<Text>();
                if (playerTextObject != null && playerTextObject.text != playerName)
                {
                    playerTextObject.text = playerName;
                    playerTextObject.color = playerColour;
                    initialised = true;
                }
           }
        }
    }