UI Navigation with gamepad

Hi

I have a problem with the ui navigation via gamepad.
It works right of the box with arrow keys, so basically I know how to set it up.

But when I try to use it with a gamepad the navigation doesn’t respond very well.
I have to keep the joystick pressed in a certain direction a long time.
It seems to get better if I increase the sensitivity in the input settings of the project but that comes with other disadvantages like the selection jumping around on the slightest move of the joystick.
I’d like to keep that untouched for now.

I don’t really know what’s going on and I hope somebody can help me here.
I’ve searched for a solution in unity answers and on google but I couldn’t find anything.
The gamepad I’m using is a XBox 360 wired windows gamepad, so nothing exotic.

EDIT: It also seems to help if I lower the repeat delay in the eventsystem in the scene.
But obviously that’s also something I don’t want to touch to solve this problem.

EDIT2: Changing the navigation to explicit doesn’t solve it either.

@grasmann

Hi, I had this problem as well and after messing around a bit with the Input Manager I found a solution.

for the Horizontal and Vertical entries in your Input Manager that you are using in your event system, set the following values(not sure if all are these are necessary but this is what worked for me): Gravity: 10, Dead: 0.9, Sensitivity 4, and uncheck snap

for your standalone input module set input actions for second to 4 and repeat delay to 0.25

I’m pretty sure the most important of the settings above is to have Dead: 0.9, it seems that when the deadzone is too small the standalone input module doesn’t work too well.

If you are using Input Manager for gameplay with the analog sticks make sure these UI settings are a different horizontal/vertical entry in the Input Manager so they don’t conflict with your gameplay control.

@grasmann @mccameron

I also have this problem. It is a bug in unity 5. The buggy code is open-source, so I wrote a fix for it. The fix only works for 5.2.2f1.

Mccameron’s solution is the easiest fix by far, but the bug can still sometimes happen.

Installing my fix is a pain and requires a bit of technical knowhow:

  1. Download the updated source from https://bitbucket.org/odomobo/ui/get/5.2.zip . You can also view my commit on bitbucket, if you desire.
  2. Compile the source code in MonoDevelop/Visual Studio, as per the README.md file.
  3. Install the compiled DLLs by copying them to the correct directory (Unity\Editor\Data\UnityExtensions\Unity\GUISystem in Windows, Unity.app/Contents/UnityExtensions/Unity/GUISystem in OSX)

If you don’t want to go through all of those steps, you can download the DLLs I compiled, and you can skip straight to step 3 as per above: Dropbox - GUISystem_5.2.2f1.zip - Simplify your life

I hope unity incorporates my fix into their next release.

The issue is fixed for me in 3.3.1p2
You may have to download it manually if it’s not showing up in your Editor’s update option yet.

For those using an older version of Unity (like me), here’s another fix:

First make unique inputs for the gamepad in the input manager; they need to be named different, like
“VerticalDpad” and “HorizontalDpad”.

Create a new script that you will attach to your EventSystem object. The script will handle the selection of buttons only if gamepad inputs are used. It should look like this:

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class EventSystemXboxDPadInputs : MonoBehaviour
{
	private GameObject currentButton;
	private AxisEventData currentAxis;
	//timer
	private float timeBetweenInputs = 0.15f; //in seconds
	private float timer = 0;

	void Update()
	{
		if(timer == 0)
		{
			currentAxis = new AxisEventData (EventSystem.current);
			currentButton = EventSystem.current.currentSelectedGameObject;

			if (Input.GetAxis("VerticalDpad") > 0) // move up
			{
				currentAxis.moveDir = MoveDirection.Up;
				ExecuteEvents.Execute(currentButton, currentAxis, ExecuteEvents.moveHandler);
				timer = timeBetweenInputs;
			}
			else if (Input.GetAxis("VerticalDpad") < 0) // move down
			{
				currentAxis.moveDir = MoveDirection.Down;
				ExecuteEvents.Execute(currentButton, currentAxis, ExecuteEvents.moveHandler);
				timer = timeBetweenInputs;
			}
			else if (Input.GetAxis("HorizontalDpad") > 0) // move right
			{
				currentAxis.moveDir = MoveDirection.Right;
				ExecuteEvents.Execute(currentButton, currentAxis, ExecuteEvents.moveHandler);
				timer = timeBetweenInputs;
			}
			else if (Input.GetAxis("HorizontalDpad") < 0) // move left
			{
				currentAxis.moveDir = MoveDirection.Left;
				ExecuteEvents.Execute(currentButton, currentAxis, ExecuteEvents.moveHandler);
				timer = timeBetweenInputs;
			}
		}

		//timer counting down
		if(timer > 0){timer -= Time.deltaTime;}else{timer = 0;}
	}
}

You can change the time between input by changing the value of “timeBetweenInputs”.

Using Unity 2018 with InControl, so I can’t exactly use the fix above, but it’s a matter of setting the RepeatDelay in the Input Manager juuust right.

I’m using 2021.1.3f1 and inControl 1.8.7 have same issue - unstable navigation speed in UI elements , speed is every time different but slow , nothing above is helping, and i found out some solution to this , after you press play button you need to go to your EventSystem object and find down EventSystem view window and make this window float by clicking on it than you can close , and this trick work for me but its hhum… crezy each time to do this