ViveSoftware / ViveInputUtility-Unity

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

How to send a button press event from a non vive controller. #21

Closed wirelessdreamer closed 6 years ago

wirelessdreamer commented 6 years ago

I have a vive controller mounted to a wireless gamepad, and need to trigger the teleport function from the game pad. tying button press x to start, and button release x to teleport. I've looked at Teleportable and ViveInputVirtualButton, but am not seeing how I should go about it. I've almost got my game updated to this utility for all my input, wish I'd of known about this months ago.

wirelessdreamer commented 6 years ago

Step 1 looks like its showing and hiding the ViveCurvePointers object for the controller, then call OnPointer3DPressExit. I'm trying to work out how to build the event data for it now.

lawwong commented 6 years ago

Here's some tips:

First of all, VIU treats tracking and input separately: ViveTracker provides tracking, ViveRaycaster provides sending input event; Prefab VivePointers and ViveCurvePointers are basically combination of ViveTracker and ViveRaycaster(inherit from Pointer3DRaycaster).

So in my opinion, the better way is to customize your own "GamepadRaycaster", and combines it with ViveTracker (which role set to TrackerRole.TrackerN).

Script StandaloneRaycaster and StandaloneEventData are basic example of customizing Pointer3DRaycaster.

Or try this example

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

public class GamepadRaycaster : Pointer3DRaycaster
{
    public string virtualButtonLeft = "Submit";
    public string virtualButtonMiddle = "Jump";
    public string virtualButtonRight = "Cancel";
    public string scrollAxisX = "Horizontal";
    public string scrollAxisY = "Vertical";

    protected override void Start()
    {
        // register 3 buttons
        buttonEventDataList.Add(new GamepadEventData(this, EventSystem.current, virtualButtonLeft, PointerEventData.InputButton.Left));
        buttonEventDataList.Add(new GamepadEventData(this, EventSystem.current, virtualButtonMiddle, PointerEventData.InputButton.Middle));
        buttonEventDataList.Add(new GamepadEventData(this, EventSystem.current, virtualButtonRight, PointerEventData.InputButton.Right));
        // ... you can register more buttons if you want
    }

    public override Vector2 GetScrollDelta()
    {
        return new Vector2(Input.GetAxis(scrollAxisX), Input.GetAxis(scrollAxisY));
    }
}

public class GamepadEventData : Pointer3DEventData
{
    private string m_virtualButtonName;

    public GamepadEventData(Pointer3DRaycaster ownerRaycaster, EventSystem eventSystem, string virtualButtonName, InputButton ibtn) : base(ownerRaycaster, eventSystem)
    {
        m_virtualButtonName = virtualButtonName;
        button = ibtn; // assign this field to let UGUI native components work correctly
    }

    public override bool GetPress() { return Input.GetButton(m_virtualButtonName); }
    public override bool GetPressDown() { return Input.GetButtonDown(m_virtualButtonName); }
    public override bool GetPressUp() { return Input.GetButtonUp(m_virtualButtonName); }
}

Notice that enabling/disabling raycasters or other controlling component must also be customized (switch their input source to your gamepad).

wirelessdreamer commented 6 years ago

Thanks, this helped me get external input working, and forgot to close the issue before.