简体   繁体   中英

Unity - Dynamically set the sprite of a UI button in loop

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.Even tSystems.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()

That error means that you are trying to access a null reference ie: 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 array is 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM