Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Value from ReadValue is incorrect when using custom Interaction

Discussion in 'Input System' started by TJHeuvel-net, Nov 28, 2019.

  1. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    818
    I'm making a repeat interaction, which triggers actions on a repeated interval. Currently my code looks like this:

    Code (csharp):
    1.  
    2.  
    3. #if UNITY_EDITOR
    4. [UnityEditor.InitializeOnLoad]
    5. #endif
    6. class RepeatInteraction : IInputInteraction
    7. {
    8.     public float RepeatDelay = 1f,
    9.                 RepeatRate = .1f;
    10.      
    11.     static RepeatInteraction()
    12.     {
    13.         InputSystem.RegisterInteraction<RepeatInteraction>();
    14.     }
    15.  
    16.     public void Process(ref InputInteractionContext context)
    17.     {
    18.         Debug.Log($"phase: {context.phase} started: {context.isStarted} val: {context.ReadValue<float>()} val2: {context.action.ReadValue<float>()}");
    19.      
    20.         if(!context.ControlIsActuated())
    21.         {
    22.             Debug.Log("Stop!");
    23.             context.Canceled();
    24.         } else if (context.timerHasExpired)
    25.         {
    26.             Debug.Log("Repeat");
    27.             context.Performed();
    28.             context.SetTimeout(RepeatRate);
    29.             return;
    30.         } else if (context.phase == InputActionPhase.Waiting)
    31.         {        
    32.             Debug.Log("Delay");
    33.          
    34.             context.PerformedAndStayStarted();        
    35.             context.SetTimeout(RepeatDelay);
    36.         }
    37.      
    38.     }
    39.  
    40.     public void Reset()
    41.     {
    42.     }
    43. }
    44.  
    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.
    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!
     
  2. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    818
    For now i've built the following workaround in the code that uses the input.

    Code (csharp):
    1.  
    2.             if (scrollActionReference.action.triggered)
    3.             {
    4.                 float val = scrollActionReference.action.ReadValue<float>();
    5.                 //Workaround, repeating actions give back the wrong value :(
    6.                 if (val == 0f)
    7.                     val = prevVal;
    8.                 prevVal = val;
    9.             }
    10.  
     
  3. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    818
    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:

    Code (csharp):
    1.  
    2. #if UNITY_EDITOR
    3. [UnityEditor.InitializeOnLoad]
    4. #endif
    5. class RepeatInteraction : IInputInteraction
    6. {
    7. #if UNITY_EDITOR
    8.     static RepeatInteraction() => InputSystem.RegisterInteraction<RepeatInteraction>();
    9. #else
    10.     [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)]
    11.     static void OnRuntimeMethodLoad() => InputSystem.RegisterInteraction<RepeatInteraction>();
    12. #endif
    13.  
     
    Last edited: Nov 29, 2019
    Alex54620, CashMonkey and rboerdijk like this.
  4. rboerdijk

    rboerdijk

    Joined:
    Aug 4, 2018
    Posts:
    96
    Aha, so this is the trick to make it work in the standalone player:
    Code (CSharp):
    1. [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)]
    Was using this as was shown in several examples, but no dice in the player:
    Code (CSharp):
    1. [RuntimeInitializeOnLoadMethod]
    Thank you for sharing your example code.
     
    TJHeuvel-net likes this.