Value from ReadValue is incorrect when using custom Interaction

I’m making a repeat interaction, which triggers actions on a repeated interval. Currently my code looks like this:

#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif
class RepeatInteraction : IInputInteraction
{
    public float RepeatDelay = 1f,
                RepeatRate = .1f;
     
    static RepeatInteraction()
    {
        InputSystem.RegisterInteraction<RepeatInteraction>();
    }

    public void Process(ref InputInteractionContext context)
    {
        Debug.Log($"phase: {context.phase} started: {context.isStarted} val: {context.ReadValue<float>()} val2: {context.action.ReadValue<float>()}");
     
        if(!context.ControlIsActuated())
        {
            Debug.Log("Stop!");
            context.Canceled();
        } else if (context.timerHasExpired)
        {
            Debug.Log("Repeat");
            context.Performed();
            context.SetTimeout(RepeatRate);
            return;
        } else if (context.phase == InputActionPhase.Waiting)
        {         
            Debug.Log("Delay");
         
            context.PerformedAndStayStarted();         
            context.SetTimeout(RepeatDelay);
        }
     
    }

    public void Reset()
    {
    }
}

It behaves as expected, when i poll isTriggered in my code it does indeed get set to true once its triggered, 1 second after its trigged, and 0.1 seconds after that while im still holding it.

However the code that consumes this read the value of a 1d axis, and ReadValue always returns 0 in repeats. Context.ReadValue does return the correct keydown value, i dont know how to pass through the correct value to the action.
5224202--520781--upload_2019-11-28_17-13-43.png
The ‘phase:’ log comes from the interaction, we can see the first value which is read from the context is correct, the second from the action isnt. The code that uses the input logs triggered and the value, the first time it is correctly -1, but at repeats it returns 0. I would expect the same value -1 be read out from the control every time.

Its really confusing there are multiple readvalues in the first place, any help is greatly appreciated!

For now i’ve built the following workaround in the code that uses the input.

            if (scrollActionReference.action.triggered)
            {
                float val = scrollActionReference.action.ReadValue<float>();
                //Workaround, repeating actions give back the wrong value :(
                if (val == 0f)
                    val = prevVal;
                prevVal = val;
            }

In the build the interaction also doesnt work because how i register it. To be honest this registering is rather cumbersome, why cant it just find all types that inherit from IInputInteraction instead? This is how the postfx stack finds custom effects too.

Right now i’m doing this:

#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif
class RepeatInteraction : IInputInteraction
{
#if UNITY_EDITOR 
    static RepeatInteraction() => InputSystem.RegisterInteraction<RepeatInteraction>();
#else
    [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)]
    static void OnRuntimeMethodLoad() => InputSystem.RegisterInteraction<RepeatInteraction>();
#endif
3 Likes

Aha, so this is the trick to make it work in the standalone player:

[UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)]

Was using this as was shown in several examples, but no dice in the player:

[RuntimeInitializeOnLoadMethod]

Thank you for sharing your example code.

1 Like