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.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Primary2DAxisClick but want Primary2DAxisClicked

Discussion in 'VR' started by adamgffrd, Jul 30, 2021.

  1. adamgffrd

    adamgffrd

    Joined:
    Sep 26, 2018
    Posts:
    35
    Wondering if there is a way to click the button, Primary2DAxisClick, and have it only register once, then go back to false, like a CLICKED method. As it stands the CLICK method that exists stays true the entire time.

    I want the user to be able to click the dpad, perform a function, and if they are still pressing the dpad down, to do nothing until it's un-pressed and then pressed again.

    Code (CSharp):
    1. private void CheckForInput()
    2.     {
    3.         foreach(XRController controller in controllers)
    4.         {
    5.             if(controller.enableInputActions)
    6.                 CheckForMovement(controller.inputDevice);
    7.         }
    8.     }
    9.  
    10.     private void CheckForMovement(InputDevice device)
    11.     {
    12.         if(device.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 position))
    13.         {  
    14.                 StartMove(position);
    15.         }
    16.  
    17.         // my own code for checking if dpad clicked, then try to DoDash
    18.         if(device.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out bool _primary2DAxisClicked))
    19.         {
    20.             float x = position.x;
    21.             float y = position.y;
    22.             if(_primary2DAxisClicked == true)
    23.             {
    24.                 // STAMINABAR CHECK HERE
    25.                 if(StaminaBar.instance.currentStamina > 10)
    26.                 {
    27.                     DoDash(x, y);
    28.                 }
    29.             }
    30.         }
    31.     }
     
  2. StayTalm_Unity

    StayTalm_Unity

    Unity Technologies

    Joined:
    May 3, 2017
    Posts:
    182
    The easiest way to do that is to cache the last retrieved value and compare it to the current one.
    Here is a quick example:

    Code (CSharp):
    1.  
    2.         bool m_Primary2DAxisClicked;
    3.        
    4.         private void CheckForMovement(UnityEngine.XR.InputDevice device)
    5.         {
    6.             if(device.TryGetFeatureValue(UnityEngine.XR.CommonUsages.primary2DAxis, out Vector2 position))
    7.             {
    8.                 //StartMove(position);
    9.             }
    10.             // my own code for checking if dpad clicked, then try to DoDash
    11.             if(device.TryGetFeatureValue(UnityEngine.XR.CommonUsages.primary2DAxisClick, out bool _primary2DAxisClicked))
    12.             {
    13.                 float x = position.x;
    14.                 float y = position.y;
    15.                 // Is now clicked, was not clicked last frame, this is the down event.
    16.                 if(_primary2DAxisClicked & !m_Primary2DAxisClicked)
    17.                 {
    18.                     // STAMINABAR CHECK HERE
    19.                 }
    20.  
    21.                 m_Primary2DAxisClicked = _primary2DAxisClicked;
    22.             }
    23.         }
    I'm using a member variable to track the state, comparing it to detect changes, then setting it before leaving the if block.

    Would that work for you?
     
    adamgffrd likes this.
  3. adamgffrd

    adamgffrd

    Joined:
    Sep 26, 2018
    Posts:
    35
    I am going to try this tonight, thank you so much! :) I will post back later on with the results, but looks like that will do the trick.
     
  4. adamgffrd

    adamgffrd

    Joined:
    Sep 26, 2018
    Posts:
    35
    This work's great, thanks alot! Sry for the delayed response.
     
    StayTalm_Unity likes this.
  5. zacharygough07

    zacharygough07

    Joined:
    Sep 11, 2021
    Posts:
    4
    Sorry to necropost, but how would you put this into it's own boolean function? I have something like this:

    Code (CSharp):
    1. bool GetXRButton(InputFeatureUsage<bool> button)
    2.     {
    3.      
    4.             bool primaryButtonClicked;
    5.  
    6.             // Is now clicked, was not clicked last frame, this is the down event
    7.             if (clicked & !primaryButtonClicked)
    8.             {
    9.                 return clicked; //rough estimate of what it would look like
    10.             }
    11.  
    12.             primaryButtonClicked = clicked;
    13.     }
    But it's not working because primaryButtonClicked was never assigned a value. Do I need to define the variable outside of the function for it to work?
    Thanks.
     
    Last edited: Nov 19, 2022
  6. zacharygough07

    zacharygough07

    Joined:
    Sep 11, 2021
    Posts:
    4
    Okay, realized some errors in my code and refined it a bit:

    Code (CSharp):
    1. bool GetXRButtonDown(InputFeatureUsage<bool> button)
    2.     {
    3.         if (targetDevice.TryGetFeatureValue(button, out bool clicked))
    4.         {
    5.             bool isDown = false;
    6.             // Is now clicked, was not clicked last frame, this is the down event
    7.             if (clicked & !isDown)
    8.             {
    9.                 return clicked;
    10.             }
    11.             else return false;
    12.  
    13.             isDown = clicked;
    14.         }
    15.         else return false;
    16.     }
    But still no luck. I think it's because the bool isDown is set to false at the start of the function, but I really don't want to clutter the rest of my script with unnecessary booleans. As it stands right now, my script would look like this:

    Code (CSharp):
    1. private bool isDown
    2.  
    3. void Update {
    4.     if (GetXRButtonDown(CommonUsages.primaryButton)) {
    5.         // do stuff here
    6.     }
    7. }
    Of course, I would have to get rid of the isDown declaration in the boolean function. It's pretty annoying and can get cluttered very fast.

    Maybe I could put it in it's own public static class in a different script, but that hasn't yielded any results either.
     
    Last edited: Nov 19, 2022