Having problems with UI

I wasn’t sure which area to put this question in as I am making a 2D game.

So in my UI (canvas) I have a game object for game over with 3 buttons (restart, level select, quit) and a game object for pause with 3 buttons (continue, level select, quit). In my event system I have the standalone input module set with my inputs and the event system has the restart button from the gave over menu.

While playing the game and die to get the game over screen to pop up I am able to use either my keyboard controls or the 360 controller I have hooked to my pc to navigate it just fine. However, when I pause the game the keyboard and controller no longer work and only way to navigate the buttons on the pause screen is by using the mouse. Each of the 6 buttons work for their intended purpose, as well as both game objects are called for at the correct time in game. How can I get both sets of buttons to work using the keyboard and controller?

I’ve tried moving the order of the game over and pause objects, tried adding a different button to the event system. Since I’m not sure what to call this problem I cant seem to figure out how to look up to see if other’s are having the same issues or not to find answers. Please help.

I vaguely recall running into an issue like this, and I think the problem was that the key/gamepad inputs only work if something already has the focus. They can advance or retreat the selection, but they can’t automatically select something if nothing is selected. (And yeah, that’s dumb, but it’s only one of several dumb things about the Unity UI event system.)

You can test whether this is the case easily: get to your pause menu, mouse over something so that it is highlighted, and then try your keyboard or gamepad. I bet it will work fine.

To work around this, you need to automatically select (by calling Select) some button when your menu appears. In my game I didn’t much care for the way that looked, so I made an invisible button (just an ordinary button but with no image, and all colors set to clear, and nothing hooked up to its onClick event), and auto-select that. Then from there the user can use keyboard/gamepad to select whatever they actually want.

Ok so I tested a couple things you mentioned. While the event system has the Restart button as its first selected button, when I pause the game when I mouse over any button till they are highlighted and the keyboard and gamepad do not work. Only the mouse works. I even tried using the Resume button as the 1st button on the event system as well as changing the order on the canvas.

Then I tried the invisible button where that was the 1st selected in the event system. At 1st I thought it worked. Killed the player resulting in the game over screen and i was able to choose the option I wanted using the keyboard or gamepad. When Restarting after game over it creates a whole new game so when I go to pause screen afterwards it allows me to use the keyboard or gamepad. However, when I kill the player again after using the pause screen to the game over screen I no longer have control over keyboard or gamepad to choose my option. The invisible button doesn’t seem to reset when another button is pressed when the next set of options pop up. So since the Restart or Resume button (depending) is pressed, they are the 2nd button on the screen where the invisible button is the 1st button. When the pause screen pops up and I select Resume, the invisible button no longer has the event system’s attention. I can navigate the pause button as many times as I want. But, as soon as I kill player and go to game over I cant navigate with keyboard or gamepad.

I’m still learning Unity and C# and am not sure how to go about telling it how to select when it starts up in code. I’m assuming it has something to do with UnityEngine.EventSystems.EventSystem.current yada yada yada, but that doesn’t mean I completely understand how to implement it right now. I’m currently reading some tutorials/documents hoping it will help me out, but its a bit confusing for me still and I’m not sure how to use properly it to fix my problem.

What I suggested only works if you add code to select the button. It’s not something you can fix only by rearranging things in the UI.

Here’s the script I use:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class SelectForNavigation : MonoBehaviour {
    public bool selectOnActivate = true;

    void OnEnable() {
        if (selectOnActivate) Invoke("Select", 0.1f);
    }
  
    public void Select() {
        GetComponent<Selectable>().Select();
    }
 }

Attach this to your “invisible” button (which by the way you should not actually make invisible until after you have it all working — otherwise it’s hard to see what’s going on). Leave the selectOnActivate property checked (true), and then it will automatically select itself when it is enabled in the scene.

I said invisible button but I had it visible the whole time with different colors to see what it was doing.
Even with that script attached to the button it’s still doing the exact same thing as it was before I attached the script except my pause and game over buttons no longer highlight, and if I choose resume from pause then kill player to go to game over I cant choose any options. Its still staying on the 2nd button which was the resume from pause and not reverting back to the invisible button.

I’m about to say forget it and just make a game over scene just so they aren’t going to conflict with each other anymore.

I suggest hanging in there a bit longer. You’re nearly there.

Add a Debug.Log to the Select method in the script. See if it’s firing when you think it should (i.e. right when the pause menu is shown).

The script, by itself, assumes that you’re activating/deactiving the button objects (or some parent object). But you could be showing/hiding the menus some other way, e.g. with a CanvasGroup component. In that case, Select won’t automatically get called — though it’s a public method, so you could call it from whatever is showing the Pause menu.

Anyway, that’s your task: arrange for the Select method to get called just after the menu is shown. You should be able to see, via the button colors, that this button gets the focus (after which keyboard/gamepad navigation should work).