ViveSoftware / ViveInputUtility-Unity

A toolkit that helps developing/prototyping VR apps.
http://u3d.as/uF7
Other
352 stars 82 forks source link

How to 'simulate' a button press for the event raycaster when not using a standard input controller #128

Closed wirelessdreamer closed 4 years ago

wirelessdreamer commented 5 years ago

Here is the basic setup i'm trying to get working, with some background.

I updated all my ui interactions to use the event raycaster setup VIU uses. it works fine with all the controllers i have configured like Vive, rift, etc. I have a controller I'm trying to set up that has a vive controller mounted to it, to track position, but its a wireless usb game pad as far as unity is concerned. I'm having trouble finding what function I can call so that when the raycaster is pointed at a button, or a slider I can send the proper events to click on the buttons.

chengnay commented 5 years ago

@wirelessdreamer You could implement your own EventData and Raycaster. Please refer to below two files, Assets\HTC.UnityPlugin\Pointer3D\StandaloneRaycaster\StandaloneEventData.cs Assets\HTC.UnityPlugin\Pointer3D\StandaloneRaycaster\StandaloneRaycaster.cs

wirelessdreamer commented 5 years ago

I'm not seeing the logic in either of those files that fires the event off. The end result I'm trying to find is call function: ClickMyMouseButton() and when i cal lthat function, it sends the mouse button left click, then call LetGoOfMyMouseButton() it sends the event for letting go of the left mouse button.

chengnay commented 5 years ago

Let's show you an example by using Example 1.UGUI image

  1. Add a Cube to VROrigin>VivePointers>Right or Left>PoseTracker
  2. Add component of Standalone Raycaster
  3. Play your scene, you will see 2 raycasters on Scene view image
  4. You can turn off the one on your controller and left the one on Cube image
  5. Point the raycaster on button and click your mouse on Game view

You will see button is being triggered by mouse left key.

In StandaloneEventData and StandaloneRaycaster, you need to define your key buttons provided by the wireless usb game pad.

lawwong commented 5 years ago

Another example:

using HTC.UnityPlugin.Pointer3D;
using UnityEngine;
using UnityEngine.EventSystems;

public class MyCustomRaycaster : Pointer3DRaycaster
{
    public KeyCode mouseButtonLeft;
    public KeyCode mouseButtonRight;

    protected override void Start()
    {
        base.Start();

        // Atleast adding one button to let this raycaster able to trigger hover/press/drag events (according to button's pressed state)
        //   IPointerEnterHandler
        //   IPointerExitHandler
        //   IPointerDownHandler
        //   IPointerUpHandler
        //   IPointerClickHandler
        //   IInitializePotentialDragHandler
        //   IBeginDragHandler
        //   IDragHandler
        //   IEndDragHandler
        //   IDropHandler
        //   IPointer3DPressEnterHandler
        //   IPointer3DPressExitHandler
        buttonEventDataList.Add(new MyCustomEventData(this, EventSystem.current, mouseButtonLeft, PointerEventData.InputButton.Left));
        buttonEventDataList.Add(new MyCustomEventData(this, EventSystem.current, mouseButtonRight, PointerEventData.InputButton.Right));
    }

    // When returns non-zero Vector2 here, then this raycaster will trigger scroll event
    //    IScrollHandler
    public override Vector2 GetScrollDelta()
    {
        return default(Vector2);
    }
}

public class MyCustomEventData : Pointer3DEventData
{
    public readonly KeyCode keyCode;

    public MyCustomEventData(Pointer3DRaycaster ownerRaycaster, EventSystem eventSystem, KeyCode keyCode, InputButton ibtn) : base(ownerRaycaster, eventSystem)
    {
        this.keyCode = keyCode;

        // Set this field properly to let most UGUI built-in component works
        // Most of them effect on InputButton.Left by default
        // Ex. UnityEngine.UI.Button will be clicked by InputButton.Left but not InputButton.Right
        button = ibtn;
    }

    public override bool GetPress() { return Input.GetKey(keyCode); }

    public override bool GetPressDown() { return Input.GetKeyDown(keyCode); }

    public override bool GetPressUp() { return Input.GetKeyUp(keyCode); }
}

In the scene, just replace ViveRaycaster with the script will do. Keep the VivePoseTracker if you want this raycaster tracking on a device. my_custom_raycaster_01 Remember to re-hook Reticle/GuidLineDrawer if you want them to work. my_custom_raycaster_02

wirelessdreamer commented 4 years ago

Thank, i've been using an approach like this for a while, and its been working great.