Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question InputSystem.QueueDeltaStateEvent for bitfield

Discussion in 'Input System' started by pajamajama, Dec 2, 2022.

  1. pajamajama

    pajamajama

    Joined:
    Oct 22, 2012
    Posts:
    66
    I have a custom device/layout. My button states are stored in a ushort bitfield.
    InputSystem.QueueDeltaStateEvent throws an error.
    Is there a workaround? Thanks much!

    [InputControl(name = "buttonA", layout = "Button", bit = 0)]
    [InputControl(name = "buttonB", layout = "Button", bit = 1)]
    public ushort buttons;


    InvalidOperationException: Cannot send delta state events against bitfield controls: Button:/AxisOrangeInputDevice/buttonB
     
  2. abegue

    abegue

    Joined:
    Jan 28, 2019
    Posts:
    24
    Got same issue and this the only place on Internet where the subject is raised so I will try to answer the question for other people who encounter the same issue.

    This error messages is triggered from this condition:
    Code (CSharp):
    1. if (control.stateBlock.bitOffset != 0)
    2.     throw new InvalidOperationException($"Cannot send delta state events against bitfield controls: {control}");
    So, you just cannot use
    InputSystem.QueueDeltaStateEvent
    on a
    InputControl
    that use bitfields (that was the case in your example with bit = 0 and bit = 1.


    In my own case, it was due to
    UnityEngine.InputSystem.TrackedDevice
    .
    Code (CSharp):
    1. [InputControl(synthetic = true)]
    2. public ButtonControl isTracked { get; private set; }
    The message appeared when trying to set the delta state event on this
    InputControl
    . However there is no bit field manipulation so I do not understand why. When debugging, its
    stateBlock.bitOffset
    is 5.

    My own code is based on
    Unity.XR.Hands.XRHandDevice
    and they use
    InputSystem.InputSystem.QueueDeltaStateEvent(isTracked, false);
    with no problem, but I cannot.

    Well, a workaround is to get ride of
    InputSystem.QueueDeltaStateEvent
    and use
    StateEvent.From
    and
    InputControl.WriteValueIntoEvent
    .
    Here is an example:
    Code (CSharp):
    1. using (StateEvent.From(this, out InputEventPtr eventPtr))
    2. {
    3. ...
    4. devicePosition.WriteValueIntoEvent(position, eventPtr);
    5. deviceRotation.WriteValueIntoEvent(rotation, eventPtr);
    6. isTracked.WriteValueIntoEvent(isDeviceTracked ? 1.0f : 0.0f, eventPtr);
    7. ...
    8. }
    Be really careful on the type you use when using
    WriteValueIntoEvent
    . For example, the
    ButtonControl
    use a float internally so you may want to set:
    buttonControl.WriteValueIntoEvent(isPressed ? 1.0f : 0.0f);
    instead of
    buttonControl.WriteValueIntoEvent(isPressed);
     
  3. wechat_os_Qy01eDJfSV7CWSHuAPwDqgMCA

    wechat_os_Qy01eDJfSV7CWSHuAPwDqgMCA

    Joined:
    Aug 4, 2022
    Posts:
    8
    I had the same issue and accidentally solved it.
    Here's my code that gives
    InvalidOperationException: Cannot send delta state events against bitfield controls
    for
    InputSystem.QueueDeltaStateEvent(poking, isPoking);
    . However,
    InputSystem.QueueDeltaStateEvent(grabbableGrabbed, isGrabbableGrabbed);
    was working fine. This is weird because poking and grabbableGrabbed have the same types.

    My solution is adding the
    offset = 0
    to the
    [InputControl]
    tag:
    Code (CSharp):
    1.     [InputControl(offset = 0)]
    2.     public ButtonControl grabbableGrabbed { get; private set; }
    3.    
    4.     [InputControl(offset = 1)]
    5.     public ButtonControl poking { get; private set; }
    and updating works fine...
    Code (CSharp):
    1. InputSystem.QueueDeltaStateEvent(grabbableGrabbed, isGrabbableGrabbed);
    2. InputSystem.QueueDeltaStateEvent(poking, isPoking);