Stop my list of Instantiated Game Objects (for Leaderboard) adding an extra object at the top

What I’m trying to do is have a scrollable list showing a list of High Scores (using the “Leaderboard Creator” plug-in). I’ve got the scroll view’s content empty in the editor, and instantiate a Prefab object (horizontal layout group with four objects: a blank space, a rank, the score, and the name – the latter three have text fields).

In a nutshell, I’ve gotten my loop to do what I want, with one problem: it adds an extra entry for the Prefab object at the top.

If I run the scene in Unity’s editor directly, it populates the top “extra” entry with the details for the last one (#15), and the list at the bottom ends at #14.

If I add +1 to the loop’s length, I’ll still get the extra entry at the top, but it’ll at least show #15 at the bottom. However, I also get an error message about the “index being outside the bounds of the array” because it’s going beyond the actual number of entries in my leaderboard, so I’m hoping to find a cleaner way to do this.

I also discovered that if I load the leaderboard through previous scenes in the game (navigating from my title menu to the leaderboard page), the extra entry at the top won’t show the info for #15, but stay with the prefab’s default empty text.

So, I sort of understand that an extra object is being instantiated because the length of the leaderboard starts at 0, but even then, Entry #0 is supposed to display the values of Rank #1. I have tried populating a list where fields have been added through the inspector, and these ones do show the #1 rank at the top as desired, but it won’t do it when instantiating the objects this way as I want (so my scroll view isn’t bigger/smaller than desired).

Is there a way I can stop the extra object being instantiated at the top without going outside the bounds of the array?

Here’s my script:

public void LoadEntries()       //Function for loading the leaderboard entries
    {
        Leaderboards.TWTTest.GetEntries(entries =>
        {
            float length = entries.Length;

            for (int i = 0; i < length; i++)        //Run the loop through the online leaderboard's data
            {
                if (entryListing.Count < entries.Length)        //If there are still more entries to load
                {
                    //entryListing.Add(entryPrefab);      //Add an entry to the script's list
                    GameObject newEntryListing = Instantiate(entryPrefab, scrollViewContent);       //Spawn the entry text display in the leaderboard

                    Text[] entryText = entryPrefab.GetComponentsInChildren<Text>();

                    if (entries[i].Rank == 1 || entries[i].Rank == 21 || entries[i].Rank == 31 || entries[i].Rank == 41)       //If the rank ends in a 1
                        entryText[0].text = entries[i].Rank.ToString() + "st";      //Populate the rank plus the suffix for 1st
                    else if (entries[i].Rank == 2 || entries[i].Rank == 22 || entries[i].Rank == 32 || entries[i].Rank == 42)       //If the rank ends in a 2
                        entryText[0].text = entries[i].Rank.ToString() + "nd";      //Populate the rank plus the suffix for 2nd
                    else if (entries[i].Rank == 3 || entries[i].Rank == 23 || entries[i].Rank == 33 || entries[i].Rank == 43)       //If the rank ends in a 3
                        entryText[0].text = entries[i].Rank.ToString() + "rd";      //Populate the rank plus the suffix for 3rd
                    else        //If the rank ends in any other number
                        entryText[0].text = entries[i].Rank.ToString() + "th";      //Populate the rank plus the standard suffix

                    entryText[1].text = entries[i].Score.ToString();        //Populate the list with the online leaderboard's scores
                    entryText[2].text = entries[i].Username;        //Populate the list with the online leaderboard's names

                }
            }

        });

    }

Here’s how the leaderboard display looks with #15 on top:

With the blank entry at the top (if I navigate to the leaderboard from the main menu):

The bottom of the leaderboard ends at #14 (when there’s 15 entries in the actual leaderboard):

Example of when I add +1 to length in the loop, it’ll show #15 at the bottom, but I also get the out of bounds error message:

Thanks in advance.

Text[] entryText = entryPrefab.GetComponentsInChildren<Text>();

This seems like an error. You are getting the texts from the prefab, instead of the instantiated newEntryListing.

Please clarify if this is by design / try changing this.

I’m not getting any errors regarding that. It’s behaving as I want it to. The error I’m getting is most certainly due to me incrementing the array length by 1, which would bring it beyond the number of entries. However, this is currently the only way I can get all the scores in my leaderboard to display. But it still doesn’t remove that blank extra one at the top.

The prefab object is a horizontal layout, with four child game objects: an empty space (I put medals here for ranks 1-3), a text object with the rank, another with the score, and a third with the name. I’m using the GetComponentsInChildren object to get the three different text objects within the prefab. That way, the script can change what text is shown when the prefab is instantiated into my list (show the correct ranks, names, etc).

I just want to know if there’s a way to stop the main array from putting that blank extra one at the top, but also displaying all my scores.

I don’t think you understood my comment. Let’s look at the following snippet.

GameObject newEntryListing = Instantiate(entryPrefab, scrollViewContent);  
Text[] entryText = entryPrefab.GetComponentsInChildren<Text>();

// ...

entryText[1].text = entries[i].Score.ToString();  
entryText[2].text = entries[i].Username;    

Here you instantiate the prefab, get the texts off it and then write to these texts. But you actually don’t get the texts off newEntryListing but entryPrefab. So you get the texts off the prefab. Thus, you are not modifying the text of the spawned entry, but the prefab, which will only effect the next spawned entry.

My guess is that because of this the first spawned entry, does not get modified at all, the next one will have the data that was intended for the first prefab and so on. It’s all off by 1.

Do you see the issue?

Oh, ok. Thanks. I just changed “entryPrefab” to “newEntryListing”, and I finally got rid of that block at the top.

Thanks again.