UI button selectable state

Hi,
I’m trying to find a way to know what the state of a button is, through script. So a component that i can attach to a button (with a reference to the button script), and ask the button in what state it currently is. I know that there is an enumerator “SelectionState”, but a button doesn’t have a public field that uses this.
e.g.:

if (MyButton.state== SelectionState.Normal)
{
     //do something
}

I’ve searched for this but no useful solution found, yet. Am I looking at it the wrong way, or is there really no variable for this?

Concrete example:
i have a button with text, the button is black and the text is green. When i hover over the button, i want them to switch colors (so green button and black text). now i have written a coroutine on to fade the text to black whenever a pointer enters the graphic of the button. However, this causes some bugs later on, when it gets a bit more complicated. but it would be way easier if i can just get the current state of the button and use a switch or something (on my text object), to change it to the correct state, according to the button.

Buttons have a interactable property

Yes, i know, but that is just to mark them “interacteble” or “not interactable”. but i want to know if the button is in highlighted or pressed or normal state.

ah, okej I thought you meant if it can be inteacrted with or not.
https://docs.unity3d.com/ScriptReference/UI.Selectable.html

isHighlighted etc will help you

hahah no, then i would’ve used that (and i’ve tried before).
True, but i cant call that on a button object through script. I need to make another class that inherits from “Selecteble” and even the, i need to pass “BaseEventData” along, to the “IsHighlighted” method. Isn’t there another way to just ask the button what it’s current state is? i would think this is like a basic thing, but i have no idea.
something like:

    public Button Button;
    void Update()
    {
        switch (Button.State)
        {
            case SelectionState.Highlighted:
                // change text color to black
                break;
            case SelectionState.Normal:
                // change text color to green
                break;
            case SelectionState.Pressed:
                // change text color to grey
                break;
            case SelectionState.Disabled:
                // change text color to red
                break;
            default:
                break;
        }
    }

I don’t like the idea of doing this in the Update method, but i’m kinda desperate at the moment haha

You could do that without script through the built in system? I dont have access to unity at the moment so cant test

No, you can only do that for one “target graphic”. In the button component, you only have room for one target graphic (the graphic it needs to change the color from, which can be text or an image or whatever you want), which in this case would be the button image. but i also want the text to change color (different colors than the button but still). So i could add a second button component and place the text object in the target graphic of this second button component, but then it acts as two buttons. then for example “on click” would fire twice when clicked on the button (once on the image and once on the text).

Maybe the others have a better idea. But one way is to create your own selectable from scratch that takes care of the sate for all child’s in the selectables tree.

I ended up writing my own selectable instead of using buttons for a tab menu. Don’t remember why at the moment but it was pretty straight forward

Hi
i want to disable 3 buttons by pressing another button
can you help me?

Hi all, I know it’s an old post but I’ll post my solution in case someone else needs to “hook” into a Button’s (or any Selectable) state.

There is a virtual method in the Selectable class that is called whenever a state change occurs.
so by overriding this method (don’t forget to call base) you can perform some action on a state change.

Example:

 protected override void DoStateTransition(SelectionState state, bool instant)
    {
        base.DoStateTransition(state, instant);
 
        switch (state)
        {
            case SelectionState.Normal :
               //do something
                break;
            case SelectionState.Highlighted :
                // do something
                break;
                // repeat for other states
        }
    }

Hope it helps someone.

3 Likes

Had a similar problem (I wanted to play a sound when the button is selected, another sound when clicked)
What I did was add an Event Trigger component on my button, set it to trigger on Selected and linked the script containing my function calling the sound.

public void OnButtonSelected(BaseEventData data)
    {
        Button btn = data.selectedObject.GetComponent<Button>();
...
    }

I wanted to change the text color of a Highlighted item with a Toggle. I used DoStateTransition and was able to do it. Thanks.

public class MyToggle : Toggle
{
    TMP_Text        m_text;

    protected override void DoStateTransition(SelectionState state, bool instant)
    {
        base.DoStateTransition(state, instant);

        if( m_text == null )
        {
            m_text = GetComponentInChildren<TMP_Text>();
        }

        switch(state)
        {
            case SelectionState.Selected:
            case SelectionState.Highlighted:
                m_text.color = new Color32(255,255,255,255);
                break;
            default:
                m_text.color = new Color32(128,128,128,255);
                break;
        }
    }
}