Search Unity

Question New Input System: Detect Touchpad click North/South (WMR/ Vive)

Discussion in 'XR Interaction Toolkit and Input' started by Tobias3112, Jan 5, 2021.

  1. Tobias3112

    Tobias3112

    Joined:
    May 9, 2017
    Posts:
    16
    I am trying out the new input system and wanted to track when the touchpad (WMR controller and Vive controller) is clicked North and South in order to activate Teleportation.
    I used the example project of the XR Toolkit as a guideline, where the teleport behavior was mapped to the Primary2DAxis. The example uses an action of type Button and a binding to the Primary2DAxis with the Interaction "Sector".

    I thought all I need to do is adding the Interaction "Press" and use the "Press Only" state in order to get the Teleport started when I press the Touchpad North or South, but it does not work.
    How can I get a teleport behavior like in the SteamVR Home application, where I need to click the Touchpad North/South in order to start teleporting and release the click to teleport?
     
  2. chris-massie

    chris-massie

    Unity Technologies

    Joined:
    Jun 23, 2020
    Posts:
    231
    The WorldInteractionDemo Scene in the Example VR project uses two different Actions to achieve a teleportation style like the SteamVR Home application. The Teleport Mode Activate when triggered will switch the active Ray Interactor into the Projectile Curve one that targets teleport Interactables, and then the Teleport Select Action uses a similar configuration to be the Select binding for that XR Controller behavior. Both actions are of type Button, and the Sector interaction is just constraining where the action will trigger. The Teleportation Interactables then are configured to trigger the teleportation On Select Exited, which happens when releasing the thumbstick back to the center. You shouldn't need to use the Press interaction, just the Sector one to limit which cardinal direction will start it.
     
  3. gosuarez

    gosuarez

    Joined:
    Nov 16, 2019
    Posts:
    5
    Hi, I'm using my vive controllers and I just noticed that the default input actions work fine for the primary2DAxis (turn/sector west-east, teleport/sector north). However, that's not the case when I try to bind the primary2DAxisClick for those actions.

    The XR input debugger indicates primary2DAxisClick (true) when pressed. I've created new actions using several action types and paths each time (e.g. button, vector 2, <XRController>{RightHand}/Primary2DAxisClick, etc), but nothing seems to work. I would really like to turn and teleport by clicking (not touching) the trackpad on my vive controllers. Has anyone resolved this using the new input system? I'm on unity 2020.3.
     
  4. chris-massie

    chris-massie

    Unity Technologies

    Joined:
    Jun 23, 2020
    Posts:
    231
    The Primary2DAxisClick is a Button control, so it will just report whether it was clicked, not the Vector2 position. You can write a new Composite binding class that binds to both the Primary2DAxis and Primary2DAxisClick that makes the Vector2 part conditional on the Primary2DAxisClick being pressed. Then make use of that Composite binding in the asset for that Input Action.
     
  5. gosuarez

    gosuarez

    Joined:
    Nov 16, 2019
    Posts:
    5
    Hi Chris, thanks for the quick response. Sadly, that approach did not work out. I did create a button (Primary2DAxisClick) with one modifier composite (Primary2DAxis) as you mentioned. However, the "snap turn provider action-based script (default)" associated with the locomotion system was only set to read Vector2 values. Therefore when implementing, the console displays an error message. If I'm not missing something else (as I'm new to the new input system), I might have to tweak a little these scripts (action turn provider and turn provider base) to read vector2 and boolean values. I hope you could tell me if I'm on the right track.
     
  6. chris-massie

    chris-massie

    Unity Technologies

    Joined:
    Jun 23, 2020
    Posts:
    231
    It should be the other way around, where the Control Type is Vector 2 and the modifier is the button type. You will need to create a custom script for the composite since there is no built-in one in the Input System for that purpose (the Button With One Modifier Composite is backwards for what you want).

    You could also override the
    ActionBasedSnapTurnProvider.ReadInput
    method to do the conversion instead.
     
  7. Thomas-Mountainborn

    Thomas-Mountainborn

    Joined:
    Jun 11, 2015
    Posts:
    501
    Did anyone end up getting this to work? When I try to make a custom composite, it just doesn't show up in the input actions UI.
     
  8. homer_3

    homer_3

    Joined:
    Jun 19, 2011
    Posts:
    111
    Kind of. To solve this I used 3 actions. A touchpad click action for detecting when the touchpad is clicked down (primary2DAxisClick with a press and release interaction), a basic touchpad action for detecting where the touchpad was currently being touched (Primary2DAxis with no interactions), and another touchpad action for detecting when the touchpad is released, because the action system is dumb and doesn't let you combine these 2 (Primary2DAxis with a release interaction).

    When processing the 2nd action, I just copied Unity's code for determining which sector you're in

    Code (CSharp):
    1. var angle = Mathf.Atan2(value.y, value.x) * Mathf.Rad2Deg;
    2.         var absAngle = Mathf.Abs(angle);
    3.         if (absAngle < 45f)
    4.             return SectorEnum.EAST;
    5.         if (absAngle > 135f)
    6.             return SectorEnum.WEST;
    7.         return angle >= 0f ? SectorEnum.NORTH : SectorEnum.SOUTH;
    Save that result to a var and set it to none on release. Then when processing the click, refer to the current sector to determine which click action to do.
     
    ceospet likes this.
  9. nawc_tg

    nawc_tg

    Joined:
    Oct 2, 2019
    Posts:
    3
    Going off the documentation, I'm trying to get the trackpad position on a Vive controller when its pressed, but receiving InvalidOperationException.

    upload_2021-11-16_16-37-6.png

    Code (CSharp):
    1.     private InputAction trackPadAction;
    2.  
    3.     private void Awake()
    4.     {
    5.         trackPadAction = new InputAction();
    6.         trackPadAction.AddCompositeBinding( "TrackPadPressed" )
    7.             .With( "Binding", "<XRController>*/primary2DAxis" )
    8.             .With( "Modifier", "<XRController>*/trackPadClicked" );
    9.         trackPadAction.performed += ( context ) => Debug.Log( $"{context.ReadValue<Vector2>()}" );
    10.     }
    11.