Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

[BUG] DPad Left and Down not working as expected. Plus workarounds

Discussion in 'Input System' started by Zethros, Jul 28, 2016.

  1. Zethros


    Jan 11, 2013
    Report Date: July 27th, 2016
    Prototype Version Date: April 6th, 2016
    Unity Version: 5.3.5f1 (Personal)

    Gamepad: Logitech F510

    (As you are aware) The Gamepad D-Pad Left and Down doesn't work as buttons. From what I understand about the D-Pad:
    • Left and Right are on an axis. Left being negative, right being positive.
    • Up and Down are on an axis. Down being negative, Up being positive (haven't tested this so i will be focusing on the horizontal).
    • Left (and most likely Down) does not work when assigned as buttons or an axis.
    • Right (and most likely Up) does work and must be used when assigned a button or an axis.
    • Once assigned as a button or an axis, Left = -1 and Right = +1
    The biggest problem?
    If you want to set Left and Right to function as buttons (specifically in conjunction with "IsHeld", On Press and On Release), the Left D-Pad will not activate these flags upon use. Only the Right D-Pad will activate the flags. (presumably the same for Down and Up)

    The Reason?
    Code (CSharp):
    1. //***InputControl.cs***
    2. private const float k_ButtonThreshold = 0.5f;
    3. private float m_ValueMultiplier = 1;
    4. //...
    5. // isHeld, wasJustPressed, wasJustReleased, respectively
    6. get { return m_State.GetCurrentValue(m_Index) * m_ValueMultiplier > k_ButtonThreshold; }
    7. get { return isHeld && (m_State.GetPreviousValue(m_Index) * m_ValueMultiplier > k_ButtonThreshold; }
    8. get { return !isHeld && (m_State.GetPreviousValue(m_Index) * m_ValueMultiplier > k_ButtonThreshold); }
    When the value is negative, these booleans always return false, preventing D-Pad Down and Left from work with IsHeld, OnPress and OnRelease.

    The Workaround:
    Code (CSharp):
    1. //***InputControl.cs***
    2. public bool isHeld
    3. {
    4.     get {
    5.         return Mathf.Abs(m_State.GetCurrentValue(m_Index) * m_ValueMultiplier) > Mathf.Abs(k_ButtonThreshold);
    6.     }
    7. }
    9. public bool wasJustPressed
    10. {
    11.     get {
    12.         return isHeld && (Mathf.Abs(m_State.GetPreviousValue(m_Index) * m_ValueMultiplier) <= Mathf.Abs(k_ButtonThreshold));
    13.     }
    14. }
    16. public bool wasJustReleased
    17. {
    18.     get { return !isHeld && (Mathf.Abs(m_State.GetPreviousValue(m_Index) * m_ValueMultiplier) > Mathf.Abs(k_ButtonThreshold)); }
    19. }
    (The Absolute on the k_ButtonThreshold is redundant but nevertheless) this, along with the following usage allows Dpads to work

    Code (CSharp):
    1. if (Input.DpadLeft.wasJustPressed && Input.DpadLeft.rawValue == -1)
    2. {
    3.     // Do things...
    4. }

    What do you think? What unforseen problems will this override create?
  2. runevision


    Nov 28, 2007
    The negative and positive properties (that are like nested controls) have various problems. We're working on a refactor where the positive and/or negative parts of an axis can instead be exposed as top-level controls. So you have leftStickX like before but also leftStickLeft and leftStickRight, and the ability to have the same kind of controls in ActionMaps you define. You'll also be able to use these as buttons.