Simple foreach() logic problem (C#)

Hi everyone!

I’m stuck with what appears to be a simple problem. I am using NGUI and Photon(don’t worry, this problem doesn’t require specific knowledge of either of them) to display a dynamic list of games in a lobby. Simple, I have done it with Unity’s built-in GUI before. The problem is, with Unity GUI, I did it in the OnGUI() function, which checked the lobby continuously, like Update(), but only instantiates one GUI item per game in the lobby. However, with NGUI, I have to use the Update() function, so I can continuously scan the lobby for new games. Start() won’t work, because it will only check the lobby once.

NGUI works a lot like the rest of Unity,so I call NGUITools.AddChild (which is basically the same as Instantiate) for each game in the lobby. Simple, should work, right? Nope, since this is the Update() function, it runs repeatedly, and therefore runs the foreach() function repeatedly, and therefore instantiates infinite copies of each game in the lobby. Not exactly what I want.

I could, of course, make it so that it only checks the lobby if the user presses a button, but I would rather not do that. Anyway, here’s my code, is there something I can do to check the lobby constantly, but only instantiate a new prefab once for each game?

Thanks for your time!

void Update()
{
        foreach (RoomInfo game in PhotonNetwork.GetRoomList())
        {
                NGUITools.AddChild(this.gameObject, button);
                UIGrid otherScript = gameObject.GetComponent<UIGrid>();
                otherScript.Reposition();
        }
}

You need to empty the parent gameObject before reloading with more children.
OR
You need to track changes in the list since the last time Update was called. So that you can add new rooms added, and remove old rooms that were removed.

Maybe something like this?
Edit: Just a note, this code may not work, it’s just an idea. Also if it did work, it might destroy the parent if the parent is maintained in the same array as the children. So you might want to check for that.

void Update()
{
        // Some function needs to be here to wipe this.gameObject's children.
        foreach (GameObject child in this.gameObject)
        {
                Destroy(child);
        }

        foreach (RoomInfo game in PhotonNetwork.GetRoomList())
        {
                NGUITools.AddChild(this.gameObject, button);
                UIGrid otherScript = gameObject.GetComponent<UIGrid>();
                otherScript.Reposition();
        }
}

Ah! Thank you, good sir. Knew I was missing something fairly simple. A few things had to be tweaked though, so, if anyone is interested, here is the final solution:

First of all, destroying the children. Required a bit of tweaking, as foreach() doesn’t work with GameObjects, but, as you noted, you can’t destroy Transforms either. So that just became this:

foreach (Transform child in this.transform)
{
       //destroys the gameObject which the "child" Transform is a part of
      Destroy(child.gameObject); 
}

Secondly, since the code was deleting and re-creating the children every single frame, clicking on the children(they are buttons, clicking on them enters the game) was impossible. Simple solution, add a timer. It doesn’t need to be continuously updated every frame, just automatically updated. So now, with the timer added, it refreshes the list automatically every 10 seconds. Works beautifully. Anyway, for those who are interested, here is the full code:

public float refreshTimer = 0;

void Update()
{
        refreshTimer -= Time.deltaTime;

        if (refreshTimer <= 0)
        {
            foreach (Transform child in this.transform)
            {
                Destroy(child.gameObject);
            }
            foreach (RoomInfo game in PhotonNetwork.GetRoomList())
            {
                NGUITools.AddChild(this.gameObject, button);
                UIGrid otherScript = gameObject.GetComponent<UIGrid>();
                otherScript.Reposition();
            }
            refreshTimer = 10;
        }
}