Button.Select(); does not highlight?

Hi.

For using a gamepad I have what ought to be a handy script going. When a menu comes up, I want a specific button to be selected and highlighted so the player can start navigating.

I put the following script on a GameObject (like the panel Parent that contains the buttons) which is inactive in the scene (or it’s activeSelf but its parent is inactive, either way…).

using UnityEngine;
using UnityEngine.UI;

public class ButtonSelector : MonoBehaviour {

	public Button selectButton;

	void OnEnable()
	{
		if(selectButton != null)
		{
			selectButton.Select();	
			print("selected button");
		}
		else
			Debug.Log ("SelectButton was null");
	}
}

The button does select, as in if I press a Submit button (spacebar, enter, Gamepad A, etc) it will activate, but the button is usually not highlighted. If I start to navigate, like move on to the next button, the next button does highlight (and select) and then I can move back to the original and it will appear highlighted. But why doesn’t it highlight the first time?

Is Select() meant to select AND highlight? If not, what do I use?

Thanks
Kevin

I am not happy with this, but I solved it by waiting a frame before selecting the button.

    IEnumerator SelectContinueButtonLater()
    {
        yield return null;
        _eventSystem.SetSelectedGameObject(null);
        _eventSystem.SetSelectedGameObject(continueButton.gameObject);
    }

Ran into this and tried different solution proposals, got it working with the yield-workaround, but it didn’t seem to make much sense. So I noticed you don’t need to wait the frame, just reset the selected GO before setting it selected again. So something along these lines does the trick for me

private void setButtonsActive(bool set)
{   
    buttons.SetActive(set);
    if (set)
        EventSystem.current.SetSelectedGameObject(buttons.GetComponentInChildren<Button>().gameObject, null);        
    else
        EventSystem.current.SetSelectedGameObject(null);
}

I know it’s a really old post, but to anyone who like me ends up here…

It is not a bug. EventSystem is a component, just another component.
Unity lifecycle says that on initializaton, all components Awake and OnEnable are called (in this order), only then all components Start is called.

So, EventSystem Awake and OnEnable may not have been called when our button.Select() was called* if we do it inside Awake or OnEnable (I had this kind of trouble with my components, where one needs to be ready first for others to start calling it).

Also, if your button game object is not enabled, trying to do

button.Select(); //button is a Button component 
button.gameObject.SetActive(true);

won’t work either (lost some good hours with this). Instead, make sure the gameObject is enabled first

button.gameObject.SetActive(true);
button.Select();

*: of course, if your button.Select() is being called some point after scene initialization, EventSystem might probably be there ready to go.

I also wasn’t a huge fan of the above solutions. I have no idea if this is correct or ideal but it solves the problem of “I toggle a menu closed/open so I want to re-select my default button, but if I was already ON that button it shows as not selected”.

private void ForceSelectGameObject(GameObject gameObject)
{
    if (EventSystem.current.currentSelectedGameObject == gameObject)
    {
        EventSystem.current.SetSelectedGameObject(null);            
    }
    EventSystem.current.SetSelectedGameObject(gameObject);    
}

This issue still exists in the latest version of Unity. I tried all of the recommended actions in this thread and nothing allows you to set a button to selected in OnEnable(). The best workaround I found was to use a runOnce bool and set the button to selected at the beginning of the update. Not pretty, but it works. I hope they address this in the future.

public class MenuSelect : MonoBehaviour
{
    public Button button;
    bool runOnce;    

    void OnEnable()
    {
        runOnce = false;
    }

    void Update()
    {
        if (runOnce == false)
        {
            button.Select();
            runOnce = true;
        }
        
        //The rest of your script here.
    }
}

For anyone who doesn’t like the presented workaround:

Putting Select() or EventSystem.SetSelectedGameObject(…) into the Start() method, rather than Awake() or OnEnable() solved it for me.

I used this

  myButton.Select();
    myButton.OnSubmit();

for setting a toggle correctly. Note this will execute the toggle events just like pushing.

I also have this issue. Seems like a bug.

Thanks, setting the eventsystem.currentSelectedGameObject to null did it for me!

I wrote up a tab-select handler that does all sorts of things for a chatroom type environment.

Basically it allows you to tab through ui components, highlights them allows you to pick an event that happens when you you hit enter while on that component even if it’s not a button. So for example if you’re in a text field, and hit enter you can send your message and you don’t have to tab to the enter button or click it, which no one really expects to do anymore. It’s pretty simple, should just have to apply it to a canvas. Might not even need to be on a canvas.

If there’s enough interest I’ll make a demo video on how to sight it up. It’s bar far the most thorough tab-input handle I’ve found in public forums.

Thank you, NOIO! Jesus H Christ, I’ve be struggling w/this problem for a few days!

I hate Unity’s UI system for many reasons. It’s like death by a thousand cuts to have to use it.

button.interactable = false;
button.interactable = true;
button.Select();

in my case (multiplayer) I made the object containing the event manager script a child of my player gameobject, so it enables with the player if that player joins late. and set Start rather than Awake.