0

I am working on Unity 4.7 project and have 15 UI buttons on my scene (named Button1, Button2, ...) and want to dynamically set the sprites or textures to it. I did it on next way:

public Button[] buttonsFlags = new Button[15];

...

public class TextureLoader
{
    public Sprite[] textures;
    public void LoadTextures(string pgNumber)
    {
        string path = "Flags/page" + pgNumber;
        textures = Resources.LoadAll<Sprite> (path);
    }
}

public void FillTheFlagsPage(string pgNumber)
    {
        textureLoader.LoadTextures(pgNumber);

        for (int i = 1; i <= textureLoader.textures.Length; i++) 
        {
            string btnName = "Button" + i.ToString ();
            buttonsFlags[i] = GameObject.Find (btnName).GetComponent<Button>();
            //buttonsFlags[i].GetComponent<Renderer>().material.mainTexture = textureLoader.textures[i];
            buttonsFlags[i].image.sprite = textureLoader.textures[i];
        }
    }

But it seems something is wrong. I get NullReferenceException: Object reference not set to an instance of an object on line buttonsFlags[i] = GameObject.Find (btnName).GetComponent(); Please help me to find right way to do this.

Edit:

NullReferenceException: Object reference not set to an instance of an object GameController.FillTheFlagsPage (System.String pgNumber) (at Assets/Scripts/GameController.cs:327) GameController.setTransitionCountries () (at Assets/Scripts/GameController.cs:225) GameController.m__6 () (at Assets/Scripts/GameController.cs:106) UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:110) UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:576) UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:718) UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53) UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35) UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44) UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52) UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269) UnityEngine.EventSystems.EventSystem:Update()

2
  • If you don't put the line numbers the stack trace doesn't help that much ;) Commented Jun 12, 2016 at 10:40
  • You have many problems. Your buttons MUST be index-numbered (start at "0"), not counting numbered (start at "1"). Secondly, I would probably urge you to NOT DO THIS. Just do it the incredibly simple "Unity-way". Put this line of code public Button[] fifteenButtons; in your script, and simply drag the buttons to that array. Note that you're currently relying on the fact that you named the game objects correctly in the editor at dev time. That's conceptually worse than "I must remember to drag them to the array". Commented Jun 12, 2016 at 15:25

1 Answer 1

2

That error means that you are trying to access a null reference i.e: either an uninitialized object, or some function/property call that should return an object actually returns null.

Given the line that spawn the error, the possible candidates are:

  • GameObject.Find(btnName) returns a null, so the next call to .GetComponent<Button>() fails. Check if the buttons GameObjects are actually in the scene.

  • the buttonsFlag arrayis not initialized, and trying to assign a value to an uninitialized array fails. However this is unlikely as you are actually initializing the array, but maybe you are calling the FillTheFlagsPage before initializing the array.

BTW You are iterating over the array of textures starting with 1 and not 0 as you should. Change that (and use (i+1).ToString() to get the name of the button) or you will end up not setting the texture of the last button (and shifting the textures of all buttons by one)

for (int i = 0; i < textureLoader.textures.Length; i++)
{
    string btnName = "Button" + (i + 1).ToString();
    Debug.Log(btnName);
    buttonsFlags[i] = GameObject.Find(btnName).GetComponent<Button>();
    //buttonsFlags[i].GetComponent<Renderer>().material.mainTexture = textureLoader.textures[i];
    buttonsFlags[i].image.sprite = textureLoader.textures[i];
}

Replace your for loop with this new for loop code then check in the console window to make sure that the last printed Button name before the error, exist in the Scene. It could be that the buttons are named Button 1, Button 2 instead of Button1 and Button2. If this is the case then add space after Button. "Button " + (i + 1).ToString();

Sign up to request clarification or add additional context in comments.

3 Comments

Great answer. Added a fixed version of his while loop + Debug.Log to see if the Button name printed actually exist in the Scene.
Thank you for reply. I have Button1, ..., Button15 (without the space) on my scene and debugged code with breakpoints so the first btnName is Button1. After that exception occurred.
It was the wrong place for calling procedure, I did it before I activated the panel on which buttons are.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.