Search Unity

Resolved Movement action not sending data continuously through events

Discussion in 'Input System' started by Ominos_Amethyst, May 8, 2022.

  1. Ominos_Amethyst

    Ominos_Amethyst

    Joined:
    Dec 15, 2021
    Posts:
    11
    [SOLVED]

    The issue was that while the event was triggering when pressing a movement button (e.g. W to move forward), I was updating the movement only there, when the event triggered. Said event would only trigger when I press and release the button, because it changed from (0.0, 1.0) to (0.0, 0.0), and that's it.

    So the solution was to cache the (normalized) Vector2 received from the event invocation and with that constantly update the movement in "Update()".

    So yeah, pretty newbie mistake.

    -------------------------------------------------------
    [THE PROBLEM]

    Hi all! I'm learning how to use the Input System together with Scriptable Objects and I'm having a little problem.

    I created a InputReaderSO (Scriptable Object) which will be responsable for handling inputs and casting to all listeners which are subscribed to the corresponding input event, in this case, the PlayerMovementController.
    I have 4 files:
    • GameInputs (Input Actions Scheme).
    • GameInputs.cs (c# file generated from the Input Actions).
    • InputReaderSO (Scriptable Object)
    • PlayerMovementController
    The Input Actions generated file is needed by the InputReaderSO in order to access the Actions Callbacks (to know when an action is being performed sort of speak)

    Here is an example on how the Input Reader is handling the Inputs and event invocations
    Code (CSharp):
    1. public void OnMove(InputAction.CallbackContext context)
    2. {
    3.     if (moveEvent != null)
    4.     {
    5.          moveEvent.Invoke((context.ReadValue<Vector2>()));
    6.     }
    7. }
    8.  
    9. public void OnLook(InputAction.CallbackContext context)
    10. {
    11.     if (lookEvent != null)
    12.     {
    13.         lookEvent.Invoke((context.ReadValue<Vector2>()));
    14.     }
    15. }
    I am subscribing and unsubscribing from the input reader events in the character controller in OnEnable and OnDisable.

    Now, this is how the Character controller is processing the data:
    Code (CSharp):
    1. private void OnMove(Vector2 moveInput)
    2. {
    3.     float baseSpeed = _isSprinting ? _sprintSpeed : _baseSpeed;
    4.     Vector3 input = new Vector3(moveInput.x, 0, moveInput.y);
    5.     transform.Translate(Time.deltaTime * baseSpeed * input);
    6. }
    7.  
    8. private void OnLook(Vector2 lookInput)
    9. {
    10.     Vector3 rotation = _cameraSensitivity * 0.01f *  new Vector3(lookInput.x, lookInput.y, 0);
    11.      
    12.     _xRotation += rotation.y;
    13.     _xRotation = Mathf.Clamp(_xRotation, -_cameraClampDegrees, _cameraClampDegrees);
    14.  
    15.     _cameraTransform.localRotation = Quaternion.Euler(_xRotation, 0, 0);
    16.         transform.Rotate(rotation.x * Vector3.up);
    17. }
    My issue is that while the camera movement is responding right, the character movement "OnMove" is only being processed once after holding a movement button (e.g. W to move forward). You can see the Input Actions Maps in the attached Image. My apologies, but I don't know how to embed a picture in the post it self.

    To recap:
    - The OnLook event (mouse input or right stick Gamepad) is sending data continuously, but the OnMove event isn't, it is being registered only once, I have to tap multiple times in order to move instead of holding the key to move.

    Thank you so much beforehand.
     

    Attached Files:

    • 5.png
      5.png
      File size:
      22.5 KB
      Views:
      205
    Last edited: May 8, 2022
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,861
    Silly suggestion, is your OnMove method being subscribed to the .performed callback one of your GameInputs class' InputAction's? By your description it looks like you may have subscribed it to .started.
     
  3. Ominos_Amethyst

    Ominos_Amethyst

    Joined:
    Dec 15, 2021
    Posts:
    11
    My apologies, I'm having difficulties understanding the suggestion.
    But if I did understand correctly, "OnMove", in the GameInputs class, is being subscribed to
    • Started
    • Performed
    • Canceled
    A small piece of code from the generated file:
    Code (CSharp):
    1. public struct GameplayActions
    2. {
    3.     private @GameInputs m_Wrapper;
    4.     public GameplayActions(@GameInputs wrapper) { m_Wrapper = wrapper; }
    5.     public InputAction @Move => m_Wrapper.m_Gameplay_Move;
    6.  
    7.     ...
    8.  
    9.     public void SetCallbacks(IGameplayActions instance)
    10.     {
    11.         ...
    12.         if (instance != null)
    13.         {
    14.                 @Move.started += instance.OnMove;
    15.                 @Move.performed += instance.OnMove;
    16.                 @Move.canceled += instance.OnMove;
    17.                 ...
    18.         }
    19.     }
    20. }
    And in the PlayerMovementController class, I'm subscribing and unsubscribing normally:
    Code (CSharp):
    1. private void OnEnable()
    2. {
    3.    _inputReaderSo.moveEvent += OnMove;
    4.    _inputReaderSo.lookEvent += OnLook;
    5.    _inputReaderSo.sprintEvent += OnSprint;
    6.    _inputReaderSo.jumpEvent += OnJump;
    7. }
    8. private void OnDisable()
    9. {
    10.    _inputReaderSo.moveEvent -= OnMove;
    11.    _inputReaderSo.lookEvent -= OnLook;
    12.    _inputReaderSo.sprintEvent -= OnSprint;
    13.    _inputReaderSo.jumpEvent -= OnJump;
    14. }
    Again, the OnLook Input and events are working as they should, the issue is the OnMove :/

    Also, sorry if I interpreted your suggestion wrongly.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,861
    Nah you've understood me correctly.

    I assume you've Debug.Log'ed in your OnMove method to make sure that it's outputting a constant stream? If not, I suppose work back through the chain to see where anything might be different between it and your OnMove setup.

    If it is outputting, something up with your OnMove code perhaps, but that doesn't seem likely.
     
  5. Ominos_Amethyst

    Ominos_Amethyst

    Joined:
    Dec 15, 2021
    Posts:
    11
    Yes! Indeed, I did Debug.Log'ed the OnMove method, the result was just 1 log when I maintained the key pressed, like if it was just registering on button tapped and not a hold type of thing. In the other hand, I did get a constant stream when I moved my mouse (OnLook).
     
  6. Ominos_Amethyst

    Ominos_Amethyst

    Joined:
    Dec 15, 2021
    Posts:
    11
    Solved it!

    The issue was that while the event was triggering when pressing a movement button (e.g. W to move forward), I was updating the movement only there, when the event triggered. Said event would only trigger when I press and release the button, because it changed from
    (0.0, 1.0)
    to
    (0.0, 0.0)
    , and that's it.

    So the solution was to cache the (normalized) Vector2 received from the event invocation and with that constantly update the movement in "Update()".

    So yeah, pretty newbie mistake.
     
  7. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    392
    Thanks!