GetControllerState() broken only when new input system "takes over"
See original GitHub issueWhile I love what the new input system does for abstraction, modularity, and a bunch of other things, I do feel strongly that you should still be able to get inputs directly for certain situations. But that’s being discussed in other threads.
I’ve written a class that reads input from the openvr API class, for my plugin where users need to get our code running straight out of the box regardless of their existing input settings (and ideally, regardless of whether they’re using the old or new SteamVR plugin version). I’ve pasted the full class at the bottom, but the key part is:
if (system != null && system.GetControllerState(deviceindex, ref state, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VRControllerState_t))))
{
ulong trigger = state.ulButtonPressed & (1UL << ((int)ButtonToCheck));
if(trigger > 0L)
{
print(ButtonToCheck + " on " + Hand + " controller is down.");
}
}
(state is a VRControllerState_t, ButtonToCheck is of type EVRButtonID, and Hand is is a custom enum that’s set to Left or Right)
If I load a new scene with this attached to a GameObject, pulling the trigger prints a message to indicate it’s working as expected.
However, if in a scene where the new input system gets loaded (indicated by several console messages about loading the action file) then it no longer works. Specifically, the GetControllerState() fills the state with empty values.
More interestingly, though, is that if you go back to the first scene that worked last time and run it, it will no longer work. But then if you restart Unity and try again, it will work.
Ideally, I need a way to get GetControllerState() working, as the new binding system is not a good option for me - the only way I can think of to make it work “out of the box” is to add actions at runtime to the bindings I want (which I couldn’t figure out how to do yet but I guess is possible) but that would also make it complicated to support users using the old version of your plugin.
But if that’s not possible, I need a way to stop GetControllerState() from failing silently. My plugin doesn’t reference anything that would cause the action system to get loaded, but a user might, and then they’d have no idea why their controls stop working. Is there a way to detect if the new action system has “taken over” so I can alert the user to set up a binding, or at least tell them where to look for a solution?
My full code below:
public class ForceControllerCheckSlim : MonoBehaviour
{
public EVRButtonId ButtonToCheck = EVRButtonId.k_EButton_SteamVR_Trigger;
public ControllerHand Hand = ControllerHand.Right;
CVRSystem system = OpenVR.System;
private uint deviceindex
{
get
{
ETrackedControllerRole role = Hand == ControllerHand.Left ? ETrackedControllerRole.LeftHand : ETrackedControllerRole.RightHand;
return system.GetTrackedDeviceIndexForControllerRole(role);
}
}
VRControllerState_t state = new VRControllerState_t();
void Update()
{
if (system != null && system.GetControllerState(deviceindex, ref state, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VRControllerState_t))))
{
ulong trigger = state.ulButtonPressed & (1UL << ((int)ButtonToCheck));
if(trigger > 0L)
{
print(ButtonToCheck + " on " + Hand + " controller is down.");
}
}
}
}
public enum ControllerHand
{
Left,
Right
}
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (1 by maintainers)
Hello @zite, in case it’s not obvious, feel free to give me a ping or otherwise indicate that an issue report belongs in a different issue tracker and I can transfer them for you.
This is in the latest release