- Home /
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
You could try :
using UnityEngine.EventSystems;
void OnEnable()
{
if(selectedButton != null)
{
EventSystem.current.SetSelectedGameObject(selectedButton, new BaseEventData());
}
}
Thanks but that didn't do it.
First of all the line there had to be
EventSystem.current.SetSelectedGameObject(selectedButton.gameObject, new BaseEventData(EventSystem.current));
assu$$anonymous$$g that 'selectedButton' was a Button and not a GameObject, and the BaseEvent Data needed an argument. I assume you meant to give it the current system?
Thanks but this resulted in the exact same behaviour as before. The buttons would be selected (proven by the fact that 'Spacebar' or other Submit buttons would activate them) but only some of them were highlighted. Oddly, it's always the same ones do or don't highlight, but there doesn't seem to be an overall rule (such as submenus not working or whatever).
Select() should select and highlight.
Have you tested in the editor by manually enabling the GameObject that script is on (via its checkbox in the Inspector)? Does it work consistently then?
Good to know Select() should highlight. Just in case I was using it wrong.
Your suggestion doesn't work but it's shown me that there's definitely buggy behaviour going on. When I launch, I get the nomal button-is-selected-but-you-can't-see-it behaviour, but after I disabled the panel via the inspector, the button didn't come back on. It wasn't even clickable. In fact, loading up any scene in the game and trying to use the UI just didn't work. All buttons stopped behaving as clickable. Something must be breaking the Event System.
The only way to clear the error was to restart the entire editor.
Now if I play the game as normal, stop the game, and re-enter play mode, none of the buttons respond. I can basically only get one play out of the game in the editor without a restart. Crazy behaviour! (and yes the Event System is still in the scene, active)
I'll open a ticket. This was the same with versions 5.3.2p2 and 5.3.2f1. It seemed in both that as soon as I tried your suggestion it broke something forever. Time.timeScale was 0 as I did this (it was a pause menu).
Actually, it's broken input across all projects.
I've uninstalled and reinstalled Unity. Tried 5.3.2f1, 5.3.2p2 and 5.3.2p3 all with clean installs. Any project that I open behaves thus:
On first Editor play the button systems seems to respond normally (until a scene change anyway). On second editor play no buttons respond to navigation or selection.
All projects, clean installs, different versions of Unity so it's not likely a Project Settings thing. This also makes it a HUGE blocker to my development process, especially considering my next build focuses on UI. I've opened a ticket but, HELP!! $$anonymous$$AYDAY!! :P
Also, Time.timescale didn't seem to affect anything as I got the same behaviour at '1' as at '0'.
Answer by noio · Mar 11, 2016 at 10:42 AM
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);
}
This is terrible butIi'm very glad to solve my issue. Thank you.
PS: so it's a Unity bug.
I've tried many other solutions over a long period of time, this one seems to finally work for me. Thank you!
using 2019.4 and the new input system, it did not highlight when I called Select when I had an object targeted in the EventSystem's "First Selected" field, but when I set it to None I no longer had to wait a frame for the highlight to work.
Answer by valtterip · Nov 11, 2016 at 08:32 AM
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 had something similar myself...
In my case I had a GUI that I was turning on and off dy deactivating and re-activating a root level GameObject as necessary. The first time I opened it in this fashion it worked fine. If I closed and re-opened it the default button would behave as if it were selected, but would not be highlighted even after re-setting the selection.
$$anonymous$$y guess is that the EvenySystem checks to see if the GameObject is already selected before it applies the selection, but that the Button script loses its highlight when deactivated and reactivated. With this in $$anonymous$$d, as with @valtterip's post, I found that nulling the selection and re-applying it seemed to do the trick.
This suggests a $$anonymous$$or issue with the Button component, if my guess above is correct. If it is supposed to maintain its selected status through re-activation then it should re-apply its highlight appropriately (I would assume this is the intent). If it's not supposed to maintain its selected status then it should de-select itself upon deactivation so that the overall system has a consistent representation of its current state.
Answer by mashiro11 · Apr 28, 2020 at 04:10 PM
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.
Answer by Pythalic · Apr 04, 2017 at 02:58 PM
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.
Yes, this is what I've been doing in my projects where I allow the use of a controller for navigation. I get the thinking that you want to do it as soon as possible, so you put it in OnEnable, but visually the user won't notice the difference between whether it's in OnEnable or in Awake/Start. Personally, I also see this method as being a lot nicer than a fiddle with a coroutine.
Answer by Arclite83 · May 11, 2020 at 08:23 AM
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);
}
Your answer
Follow this Question
Related Questions
How to set UI button as selected on mouse over 1 Answer
Get button under mouse 1 Answer
UI button always selected? 0 Answers
UI Button not sending event on IOS build only 1 Answer
UI: Mouse events not working 1 Answer