Single variable for multiple UI Images

Hi, this is my first post on the forum so I hope I’m doing it correctly.
I have a canvas whose children are a background image, some buttons, icons (images) and 4 UI Images that act as panels in my menu scene.
Each of the panels contain other kind of stuff like labels, slider, toggle and so on.

I want these UI Image panels to be visible when I press a button.
If I press “Start” button I want to see “StartPanel” with its own stuff.

When I switch to “Options” panel (I only make examples) I want all the active panels to be deactivated and I only want to “OptionPanel” to be visible.

Now the problem comes because I’d like to have a single public variable “MyCorrectPanels” that when “Start” button is pressed, becomes the “StartPanel” (with Find.Tag) and I can do MyCorrectPanel.SetActive(true);
and when “Options” button is pressed, hide all the panels and show MyCorrectPanel (which is now “OptionsPanel”).

It seems a bit confusing, but my idea is very simple: have a single variable that can activate whether one or other panel based on its tag.

The problem is there’s not any method like “Image.FindWithTag” like on GameObjects.

Could you please help me?
Thank you in advance

I would handle this a lot differently then the way you’re describing. I would use a enum to create game states. and when you press the btn “OptionsPanel” it would change the game state to “Options” and the same for “StartPanel”
Then I would do a sendmessage(“stagechanged”)

then you have a small script on the UI objects that receive the sendmessage(), and do a simple if statement to check what the current state is and if enable or disable the UI.


to answer your post,
it sounds like you’re using MyCorrectPanel as a string. and when you press the btn you’re changing the string. and then you’re doing a Find.
__UIarray = [u]GameObject.FindGameObjectsWithTag__(MyCorrectPanel);[/u]
__foreach ([u]GameObject__ UI in UIarray)[/u]
{
//enable or disable to UI gameobject
}

An image is a gameobject… Just like you don’t do image.SetActive(true), you would have to do image.gameobject.SetActive(true);

Personally I’m not a big fan of sendmessage. Makes things harder to debug for one. Would prefer just calling the script directly with GetComponent calls.

1 Like

Thanks for the two answers.
If UI Images are GameObjects, why can’t I use the FindWithTag?

public class MenuButtons : MonoBehaviour {

    // Use this for initialization

    public GameObject LittlePanel;
    public Slider MyVolSlider;
    AudioSource MyMusic;

    public GameObject CorrectPanel;

    public void Start()
    {
        MyMusic = GetComponent<AudioSource> ();                            //Get the Audio Reference
    }

    public void ButtonClicked(RectTransform Clicked)                    //This recognizes which button I cliccked
    {
        Debug.Log ("The button clicked was " + Clicked.name);

        switch (Clicked.name)
        {
        case "btn_enroll":
            ;
            break;

        case "btn_settings":
            ;
            break;

        case "btn_volume":
            CorrectPanel = GameObject.FindWithTag ("Panel");
            CorrectPanel.SetActive (true);
            Debug.Log (CorrectPanel.name);
            ;
            break;

        case "btn_controls":
            ;
            break;

        case "btn_credits":
            ;
            break;

        case "btn_quit":
            Application.Quit ();
            break;

        }
    }

I don’t see where you are looking for an image.
I see you are looking for a single gameobject CorrectPanel. so is the UI image a subobject the “Panel” gameObject?
you could do
GameObject myImage = GameObject.Find(CorrectPanel.name + “/nameOfImage”);
and then do what ever to that.
myImage.getComponent().blablabla

1 Like

This is way over-complicated. Why build a state machine for something like this? Declare your panel array and directly set it in the Inspector. Then add a click event listener to your buttons and point it to a method like

public void ShowPanel(GameObject panel)
{
    // turn off every panel
    foreach (var pnl in panels)
    {
        pnl.SetActive(false);
    }
    // turn on the one you care about
    panel.SetActive(true);
}

And drag-drop the panel you’re turning on into the argument slot in the listener.

1 Like

No, i have 5 UI Images all with tag “Panel” but they are not GameObnects, the are part of the UI.
In each case of the switch I will remove all Images of tag “Panel” and I will activate Image of Name “X”.

Will GameObject.Find and GameObjects.FindWithTag work for Ui Images?

Thanks for the answer

I guess I should clarify. Images are components that are attached to gameobjects in your scene. It’s not a question of “part of the ui”. It’s still a gameobject that is in your scene.

Don’t use GameObject.Find. It’s slow. I probably wouldn’t even use FindWithTag, but that’s better then just Find.

If you find a gameobject that has the proper tag, then you need to grab the image component.

so, gameobject.GetComponent().sprite = “somesprite”; for example. But, if you just plan to turn off the gameobject, you don’t need the component.

I don’t know what you mean by why can’t you use FindWithTag on them. If they are tagged properly, it should find them.

Also, @KelsoMRK gave an example of how I might do it. But you could also store the last panel opened in a variable and if you only have one panel open at a time, you could simply turn it off, turn on the new one and assign the new to that variable. But with only a few objects, looping through them isn’t a big deal.

1 Like

ok, so try this out

case "btn_volume":
            CorrectPanel = GameObject.FindWithTag ("Panel");

            GameObject[] UIarray = GameObject.FindGameObjectsWithTag("Panel");

            foreach (GameObject UI in UIarray)
            {
            UI.SetActive (true);
            Debug.Log (UI.name);
            }
            break;
1 Like

Stop it. No. Don’t pass magic strings around :slight_smile:

1 Like

I did exactly what you said but it does activate nothing.
Also debug UI.name does not show anything.

That’s the result:
http://i64.tinypic.com/11sl368.png

But, if I add the same tag to a Button, it works. With the UI Images it doesn’t

I’m sorry I’m insisting but I am a total beginner

If that code does nothing, then the array is probably empty or you’re not hitting that case statement.

Are you sure your object are tagged with Panel and you’re not naming them Panel?
If that is fine, just make sure you’re hitting the case statement.

1 Like

per your screen shot, the game object you have selected is untagged.
in the top right you can change it’s tag. please change it to “Panel”

        case "btn_volume":
            Debug.Log ("What are you doing");

            //CorrectPanel = GameObject.FindWithTag ("Panel");

            GameObject[] UIarray = GameObject.FindGameObjectsWithTag("Panel");


            foreach (GameObject UI in UIarray)
            {
                UI.SetActive (false);
                Debug.Log ("The Image is" + UI.name);
            }

            ;
            break;

This happens if tag “Panel” is assigned to the 4 UI Images: (it does not hit the case)
http://i63.tinypic.com/xnas6f.png

case "btn_volume":
            Debug.Log ("What are you doing");

            CorrectPanel = GameObject.FindWithTag ("Panel");

            Debug.Log ("Single UI is" + CorrectPanel.name);

            //GameObject[] UIarray = GameObject.FindGameObjectsWithTag("Panel");


       
            break;

And this if “Panel” is assigned only to 1 image: (it hits the case)
http://i67.tinypic.com/33kue6x.png

This is what happens if I assign “Panel” tag to one of the buttons: (it hits the case and it gives me the name)
http://i66.tinypic.com/2w3dlsh.png

And, in the end, if I assign “Panels” to all the buttons: (it hits the case and it gives me the names):

case "btn_volume":
            CorrectPanel = GameObject.FindWithTag ("Panel");

            GameObject[] UIarray = GameObject.FindGameObjectsWithTag("Panel");

            foreach (GameObject UI in UIarray)
            {
                UI.SetActive (true);
                Debug.Log (UI.name);
            }
            break;

http://i64.tinypic.com/28gsb5y.png

Why does it work only with buttons?

Sorry, the last photo is incorrect:
http://i66.tinypic.com/2dm7dae.png

are you saying that you are clicking on the Icon to left of the button?

1 Like

No, I was clicking on the button.

At the end I manually added the 4 UI images to the array and it works.

Sorry for the disturb, thanks very much to all!

that’s too bad you had to manually populate the array. As long as you got it working. and you’re learning, so that’s always good.

This is the way it should be done. It would take 2 seconds of looking in the Inspector to see the array was empty instead of hunting around the scene and checking every panel to make sure it was tagged correctly.

magic.strings.are.evil…

1 Like

Do this