Get DPad input value via GetButton instead of GetAxis?

Greetings,

I have this generic USB controller. I’m trying to detect its DPad (or analog stick) input values.

Using Input.GetAxis("Horizontal") and Input.GetAxis("Vertical") does work (assuming that I set the joystick axis to X for horizontal, and Y for vertical)

I don’t want to deal with GetAxis. Is there anyway I could get the values via Input.GetButton? The only reserved button names I know for joystick in Unity are joystick button N where N could be 0, 1, 2, 3, etc. Is there something like a dpad button 0?

Any help is appreciated, thanks.

Another solution to this, a bit clunky but it works.

public class Dpad : Monobehaviour {

    private float dpadX;
    private float dpadY;
    private bool leftDpadPressed;
    private bool rightDpadPressed;
    private bool upDpadPressed;
    private bool downDpadPressed;
    private bool currentlyReleased;

private void Start(){
 currentlyReleased = true;	
 }

 private void Update()
    {
        dpadX = Input.GetAxis("Dpad X");
        dpadY = Input.GetAxis("Dpad Y");
        


        if (dpadX == -1)
        {
            leftDpadPressed = true;
            if(leftDpadPressed && currentlyReleased)
            {
                //Fire events
               
                print("LEFT");
            }

            currentlyReleased = false;
        }
        if(dpadX == 1)
        {
            rightDpadPressed = true;
            if(rightDpadPressed && currentlyReleased)
            {
                //Fire events
                
                print("RIGHT");
            }
            currentlyReleased = false;
        }
        if (dpadY == -1)
        {
            downDpadPressed = true;
            if (downDpadPressed && currentlyReleased)
            {
                //Fire events
               
                print("DOWN");
            }
            currentlyReleased = false;
        }
        if (dpadY == 1)
        {
            upDpadPressed = true;
            if (upDpadPressed && currentlyReleased)
            {
                //Fire events
              
                print("UP");
            }
            currentlyReleased = false;
        }
        if (dpadY == 0 && dpadX == 0)
        {
            upDpadPressed = false;
            downDpadPressed = false;
            leftDpadPressed = false;
            rightDpadPressed = false;
            currentlyReleased = true;
        }

    }


}

From what I’ve been reading it seems that Unity does not allow you to read the D-Pad as buttons on Windows (although you can on Mac & Linux). This is really unfortunate because it makes it much harder than it should be to read discrete events from these buttons but I found this other answer which has some (rather clunky) solutions.

I haven’t tested it, but using Input.GetAxisRaw might go a long way in getting the behaviour you desire. It doesn’t apply smoothing so hitting the D-Pad left (for example) should return -1 immediately.
So something like

bool GetDPadButton(string button)
{
    if (button == "right") return Input.GetAxisRaw("DPadX") == 1;
    if (button == "down") return Input.GetAxisRaw("DPadY") == -1;
    if (button == "left") return Input.GetAxisRaw("DPadX") == -1;
    if (button == "up") return Input.GetAxisRaw("DPadY") == 1;
}

could work if the Input settings are properly set up. However, I’m not sure what values are returned when two D Pad buttons are pressed or if there are other cases where one of the axis would return a value between 0 and 1.

DPad X or Y are triggering endless events when they’ll rich the value of 1 or -1.

The Input.GetButtonDown/GetButtonDown are giving just one state wich let us to increment a value one by one for exemple. Like a Toggle basically.

I was trying some solutions but no solution is working.

Maybe someone will find a solution for that.

If anyone is still running into this issue one option is to save the previous state of the axis, and if its the same ignore it. this will allow you to only act on each button press.

		var _dir = CrossPlatformInputManager.GetAxis("DPadUpDown");
		if(_dir == LastButtonState)
			return;

		//if its diff then update our last state save that
		LastButtonState = _dir;

		if(_dir > 0)
			//do something awesome
		else if(_dir < 0)
			//Do something awesome in a diff direction

Unity, could you please remedy this?

Here is something that works for me, but i am not too sure about performance cost and also works if you hold the input down.


I used it for my joystick and DPad input. The Debug Statement is where i will place my functionality for the input.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MenuController : MonoBehaviour
{
    private bool inputAllowed;

    void Start()
    {
        inputAllowed = true;
    }

    void Update()
    {
        if (inputAllowed)
        {
            StartCoroutine(MenuInput());
        }        
    }

    private IEnumerator MenuInput()
    {
        if (Input.GetAxis("Vertical") == -1 || Input.GetAxis("DPadY") == -1)
        {
            Debug.Log("user has pressed down");
            inputAllowed = false;

            yield return new WaitForSeconds(0.1f);
            inputAllowed = true;
        }
    }
}

My logic is that the coroutine will not be too costly because even though it is called every frame, it only yields when there is input and then disables the coroutine from being called until the coroutine finishes. Please correct me if I am wrong.