New Error report after fixing a problem.

I had a problem with the buttons not working when I first opened my game. They only worked after opening the game from the second attempt.
I have now corrected that by using a separate script for the buttons OnClick Events and attaching that to the main camera.

However now I have new problem, the player skins and level pictures( both from sprites) do not appear until the second time and I keep getting this new error report.

UnityException: Transform child out of bounds
MainMenu.ChangePlayerSkin (Int32 index) (at Assets/Scripts/MainMenu.cs:129)
MainMenu.Start () (at Assets/Scripts/MainMenu.cs:40)

Please advise what I can do to prevent the out of bounds.
Can I set a limit to the bounds, there are 16 different player skins which I assume would be a count up to 15?

The public Game Objects are all allocated correctly.

This is the Main Menu C# code:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections;

public class LevelData
{
public LevelData (string levelName)
{
string data = PlayerPrefs.GetString(levelName);
if (data == “”)
return;
string[ ] allData = data.Split (‘&’);
BestTime = float.Parse (allData [0]);
}
public float BestTime { set; get;}
public float GoldTime { set; get;}
}

public class MainMenu: MonoBehaviour

{ public GameObject levelButtonPrefab;
public GameObject levelButtonContainer;
public GameObject playerTexturePrefab;
public GameObject playerTextureContainer;
public Text currencyText;

public Material playerMaterial;
private Transform cameraTransform;
private Transform cameraDesiredLookAt;

private bool nextLevelLocked=false;

private int [ ]costs ={0,150,150,150,300,300,300,300,500,500,500,500,1000,1500,1500,2000};

private void Start()
{
ChangePlayerSkin (GameManager.Instance.currentSkinIndex);
currencyText.text =GameManager.Instance.currency.ToString ();
cameraTransform = Camera.main.transform;

Sprite[ ] thumbnails=Resources.LoadAll(“Levels”);
foreach (Sprite thumbnail in thumbnails)
{
GameObject container = Instantiate (levelButtonPrefab)as GameObject;
container.GetComponent ().sprite = thumbnail;
container.transform.SetParent (levelButtonContainer.transform,false);
LevelData level = new LevelData (thumbnail.name);

string minutes=((int) level.BestTime / 60).ToString(“00”);
string seconds=((int) level.BestTime % 60).ToString(“00.00”);

container.transform.GetChild(0).GetChild(0).GetComponent().text= (level.BestTime !=0.0f)
? minutes + “:” + seconds: “No Time”;
container.transform.GetChild (1).GetComponent().enabled = nextLevelLocked;
container.GetComponent ().interactable = !nextLevelLocked;

if (level.BestTime == 0.0f) {
nextLevelLocked = true;
}

string sceneName = thumbnail.name;
container.GetComponent ().onClick.AddListener (()=> LoadLevel(sceneName));

}

int textureIndex = 0;
Sprite[ ] textures = Resources.LoadAll (“Player”);
foreach (Sprite texture in textures)
{
GameObject container = Instantiate (playerTexturePrefab)as GameObject;
container.GetComponent ().sprite = texture;
container.transform.SetParent (playerTextureContainer.transform,false);

int index = textureIndex;
container.GetComponent ().onClick.AddListener (()=> ChangePlayerSkin(index));
container.transform.GetChild (0).GetChild (0).GetComponent().text = costs [index].ToString ();
if ((GameManager.Instance.skinAvailability & 1 << index) == 1 << index)
{
container.transform.GetChild (0).gameObject.SetActive (false);
}
textureIndex ++;
}
}
private void Update()
{
if (cameraDesiredLookAt != null) {
cameraTransform.rotation = Quaternion.Slerp (cameraTransform.rotation, cameraDesiredLookAt.rotation, 3 * Time.deltaTime);
}

}

private void LoadLevel (string sceneName)
{
SceneManager.LoadScene (sceneName);
}

private void ChangePlayerSkin(int index)
{
if ((GameManager.Instance.skinAvailability & 1 << index) == 1 << index) {
float x = (index % 4) * 0.25f;
float y = ((int)index / 4) * 0.25f;
if (y == 0.0f)
y = 0.75f;
else if (y == 0.25f)
y = 0.50f;
else if (y == 0.50f)
y = 0.25f;
else if (y == 0.75f)
y = 0.0f;

playerMaterial.SetTextureOffset (“_MainTex”, new Vector2 (x, y));
GameManager.Instance.currentSkinIndex = index;
GameManager.Instance.Save ();
}
else
{
int cost = costs [index];
if (GameManager.Instance.currency >= cost)
{
GameManager.Instance.currency -= cost;
GameManager.Instance.skinAvailability += 1 << index;
GameManager.Instance.Save ();
currencyText.text = GameManager.Instance.currency.ToString();
playerTextureContainer.transform.GetChild (index).GetChild (0).gameObject.SetActive (false);
ChangePlayerSkin (index);
}
}
}

[/code]

Can you add an open [ CODE ] tag please.

1 Like

Hi, Thanks for the reply.
Hopefully this has an Open Code tag

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections;

public class LevelData
{  
    public LevelData (string levelName)
    {
        string data = PlayerPrefs.GetString(levelName);
        if (data == "")
            return;
        string[] allData = data.Split ('&');
        BestTime = float.Parse (allData [0]);
    }
    public float BestTime { set; get;}
    public float GoldTime { set; get;}
}

public class MainMenu: MonoBehaviour

{    public GameObject levelButtonPrefab;
    public GameObject levelButtonContainer;
    public GameObject playerTexturePrefab;
    public GameObject playerTextureContainer;
    public Text currencyText;

    public Material playerMaterial;
    private Transform cameraTransform;
    private Transform cameraDesiredLookAt;


    private bool nextLevelLocked=false;

    private int []costs ={0,150,150,150,300,300,300,300,500,500,500,500,1000,1500,1500,2000};




    private void Start()
    {    ChangePlayerSkin (GameManager.Instance.currentSkinIndex);
        currencyText.text =GameManager.Instance.currency.ToString ();
        cameraTransform = Camera.main.transform;

        Sprite[] thumbnails=Resources.LoadAll<Sprite>("Levels");
        foreach (Sprite thumbnail in thumbnails)
        {
            GameObject container = Instantiate (levelButtonPrefab)as GameObject;
            container.GetComponent<Image> ().sprite = thumbnail;
            container.transform.SetParent (levelButtonContainer.transform,false);
            LevelData level = new LevelData (thumbnail.name);

            string minutes=((int) level.BestTime / 60).ToString("00");
            string seconds=((int) level.BestTime % 60).ToString("00.00");


            container.transform.GetChild(0).GetChild(0).GetComponent<Text>().text= (level.BestTime !=0.0f)
                ? minutes + ":" + seconds: "No Time";
            container.transform.GetChild (1).GetComponent<Image>().enabled = nextLevelLocked;
            container.GetComponent<Button> ().interactable = !nextLevelLocked;


            if (level.BestTime == 0.0f) {
                nextLevelLocked = true;
            }

            string sceneName = thumbnail.name;
            container.GetComponent<Button> ().onClick.AddListener (()=> LoadLevel(sceneName));

        }

        int textureIndex = 0;
        Sprite[] textures = Resources.LoadAll<Sprite> ("Player");
        foreach (Sprite texture in textures)
        {
            GameObject container = Instantiate (playerTexturePrefab)as GameObject;
            container.GetComponent<Image> ().sprite = texture;
            container.transform.SetParent (playerTextureContainer.transform,false);  

            int index = textureIndex;
            container.GetComponent<Button> ().onClick.AddListener (()=> ChangePlayerSkin(index));
            container.transform.GetChild (0).GetChild (0).GetComponent<Text>().text = costs [index].ToString ();
            if ((GameManager.Instance.skinAvailability & 1 << index) == 1 << index)
            {
                container.transform.GetChild (0).gameObject.SetActive (false);
            }
            textureIndex ++;
        }
    }
    private void Update()
    {
        if (cameraDesiredLookAt != null) {
            cameraTransform.rotation = Quaternion.Slerp (cameraTransform.rotation, cameraDesiredLookAt.rotation, 3 * Time.deltaTime);
        }  

    }

    private void LoadLevel (string sceneName)
    {
        SceneManager.LoadScene (sceneName);
    }

    private void ChangePlayerSkin(int index)
    {
        if ((GameManager.Instance.skinAvailability & 1 << index) == 1 << index) {
            float x = (index % 4) * 0.25f;
            float y = ((int)index / 4) * 0.25f;
            if (y == 0.0f)
                y = 0.75f;
            else if (y == 0.25f)
                y = 0.50f;
            else if (y == 0.50f)
                y = 0.25f;
            else if (y == 0.75f)
                y = 0.0f;

            playerMaterial.SetTextureOffset ("_MainTex", new Vector2 (x, y));
            GameManager.Instance.currentSkinIndex = index;
            GameManager.Instance.Save ();
        }
        else
        {
            int cost = costs [index];
            if (GameManager.Instance.currency >= cost)
            {
                GameManager.Instance.currency -= cost;
                GameManager.Instance.skinAvailability += 1 << index;
                GameManager.Instance.Save ();
                currencyText.text = GameManager.Instance.currency.ToString();
                playerTextureContainer.transform.GetChild (index).GetChild (0).gameObject.SetActive (false);
                ChangePlayerSkin (index);
            }
        }
    }

Thanks for your help.
I solved the problem this evening, I made a new script for the buttons and moved the level script to a void Awake so every start up and Initial start is okay either way.
Many Thanks