Search Unity

Question VR Controller Input not matching "Input.GetKeyDown"

Discussion in 'AR/VR (XR) Discussion' started by Cooleobrad, Jun 24, 2020.

  1. Cooleobrad

    Cooleobrad

    Joined:
    Dec 16, 2016
    Posts:
    15
    I'm trying to replicate code where the condition is just if the space bar is pressed,
    Code (CSharp):
    1. Input.GetKeyDown(KeyCode.Space)
    but for VR with the primary "A" button on an Oculus Rift controller using Unity XR.
    Code (CSharp):
    1. public class ReadInput : MonoBehaviour
    2. {
    3.     //Assigned to the RightHand Controller
    4.     public XRController controller = null;
    5.     InputDevice device;
    6.     void Start (){
    7.         device = Input.GetDeviceAtXRNode(controller.controllerNode);
    8.     }
    9.     void Update()
    10.     {
    11. if(device.TryGetFeatureValue(CommonUsages.primaryButton, out bool buttonValue) && buttonValue)
    12.         {
    13.             Debug.Log(" pressing a");
    14.         }
    15. }
    While the VR solution technically works, it is breaking the game in a way that isn't occuring with just the space bar. Seemingly it is returning true more than it should, but I can't totally figure it out. Setting the boolean to false before the if statement doesn't fix it. Using the code for getting the KeyCode.Space does fix it. Shouldn't the VR code be doing the exact same thing as the KeyCode.Space line except instead of registering a space button press it registers the 'A' button press on my VR controller?
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    No, they don't do the same thing. Input.GetKeyDown returns true only on the first frame when the button is pressed. InputDevice.TryGetFeatureValue returns true on every frame while the button is pressed.

    If you want the same behavior, you'll need to keep track yourself of whether the button was down on the previous frame.
     
  3. Cooleobrad

    Cooleobrad

    Joined:
    Dec 16, 2016
    Posts:
    15
    That seems really clunky. I'm guessing there isn't another function in the XR toolkit that checks for button presses only on the first frame? I'm not too sure how I would check for something like this on my own.
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    It's not a big deal. Do something like this.

    Code (CSharp):
    1.     public class ReadInput : MonoBehaviour
    2.     {
    3.         bool wasDown = false;
    4.         bool isDown = false;
    5.        
    6.         //Assigned to the RightHand Controller
    7.         public XRController controller = null;
    8.         InputDevice device;
    9.  
    10.         void Start (){
    11.             device = Input.GetDeviceAtXRNode(controller.controllerNode);
    12.         }
    13.  
    14.         void Update() {
    15.             wasDown = isDown;
    16.             bool buttonValue = false;
    17.             device.TryGetFeatureValue(CommonUsages.primaryButton, out isDown);
    18.         }
    19.        
    20.         public static void ButtonDown() {
    21.             return isDown && !wasDown;
    22.         }
    23.         public static void Button() {
    24.             return isDown;
    25.         }
    26.         public static void ButtonUp() {
    27.             return wasDown && !isDown;
    28.         }
    29.     }
     
    Cooleobrad likes this.
  5. Cooleobrad

    Cooleobrad

    Joined:
    Dec 16, 2016
    Posts:
    15
    Thank you, but this code doesn't seem to compile or work properly. When just trying to run this I get the error

    Severity Code Description Project File Line Suppression State
    Error CS0120 An object reference is required for the non-static field, method, or property 'InterfaceManager.isDown' Assembly-CSharp
    Changing to just public voids doesn't let me return and changing these to public bools gives me the same issues as before.
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    It was just a sketch, typed out of my head on the fly between other tasks. That's what I meant "something like" to indicate.

    But yeah, looks like you need to either add static to isDown, or remove static from the methods — all depending on how you want to use this.

    If you would like to hire someone to write the code for you, I am available — just PM me.