Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Question How do you get values from InputActionReference?

Discussion in 'Input System' started by laurentlavigne, Apr 12, 2024.

  1. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,384
    This isn't moving. Are there pieces of input system scaffolding missing in this code?

    Code (CSharp):
    1. [DefaultExecutionOrder(-30000)]
    2. public class PoseDriver : MonoBehaviour
    3. {
    4.     public InputActionReference position,
    5.                                                             rotation;
    6.  
    7.     protected virtual void OnEnable()
    8.     {
    9.         position.action.Enable();
    10.         rotation.action.Enable();
    11.         Application.onBeforeRender += OnBeforeRender;
    12.     }
    13.  
    14.     protected virtual void OnDisable()
    15.     {
    16.         position.action.Disable();
    17.         rotation.action.Disable();
    18.         Application.onBeforeRender -= OnBeforeRender;
    19.     }
    20.  
    21.     [BeforeRenderOrder(-30000)] protected virtual void OnBeforeRender()
    22.     {
    23.         transform.localPosition = position.action.ReadValue<Vector3>();
    24.         transform.localRotation = rotation.action.ReadValue<Quaternion>();
    25.     }
    26. }
    upload_2024-4-12_13-20-33.png
     
  2. Abdo-Reda

    Abdo-Reda

    Joined:
    Oct 8, 2015
    Posts:
    11
    I think you are missing a playerInput component. You need to have a playerInput component that references the inputActionAsset and also has the actionMap Left as the current active action map. I think without the playerInput component, none of the actions you have will be listened to and their values won't be updated.

    If you want to avoid having a playerInput, you can try listening to the bindings or button controls on the device directly. You will need to get the ButtonControl from your device.

    Here is a snippet of code that may give some ideas
    Code (CSharp):
    1. action.GetBindingDisplayString(bindingIndex, out _, out controlPath);
    2. pauseButton = (ButtonControl) playerDevice[controlPath];
    3. pauseButton.ReadValue(); //so on ...
     
  3. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,384
    I know that IS is next-gen convoluted but, in this case, what I wrote works as-is.
    it's just that there is a bug in it where the action map dies, from time to time.
    the "fix" is to turn on generate c# class o_O
     
    Whatever560 likes this.
  4. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    525
    Does it happen in builds or in editor ? I do have regular issues with "dying" action maps in builds, it also happens in editor but less often. I have several wrappers that just spam .Enable() on input actions wherever I need (I do it in the Update Loop, OnEnable was not enough)

    OnDisable is the same as yours. I'll keep in mind if what you said about c# class generation..
    Code (CSharp):
    1.    public void Update()
    2.         {
    3.             if (!_inputActionRef) return;
    4.  
    5.             if(_inputActionRef.action.enabled.Not())
    6.                 try
    7.                 {
    8.                     _inputActionRef.action.Enable();
    9.                 }catch(Exception e)
    10.                 {
    11.                     //your own
    12.                 }
    13. }
    14.  
    15.  
    Also this if It helps :
    Code (CSharp):
    1.    public static class InputSystemExtensions
    2.     {
    3.         /// <summary>
    4.         /// A read value that also read binding composited with modifiers.
    5.         /// </summary>
    6.         /// <typeparam name="T"></typeparam>
    7.         /// <returns></returns>
    8.         public static T ReadValueBetter<T>(this InputAction action)
    9.         {
    10.             var value = action.ReadValueAsObject();
    11.             if (value == null) return default;
    12.             if (value.GetType() == typeof(T)) return (T) value;
    13.             IndusLogger.Error(nameof(ReadValueBetter), $"Can't cast <{value.GetType().Name}> to <{typeof(T).Name}>");
    14.             return default;
    15.         }
    16.     }
     
    Last edited: Apr 19, 2024
  5. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,384
    Here is the solution:
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityEngine.InputSystem;
    4.  
    5. public class InputManager : MonoBehaviour
    6. {
    7.     public InputActionAsset inputMap;
    8.  
    9.     void Awake()
    10.     {
    11.         InputSystem.settings.SetInternalFeatureFlag("USE_OPTIMIZED_CONTROLS", true);
    12.     }
    13.  
    14.     void OnEnable()
    15.     {
    16.         inputMap.Enable();
    17.     }
    18.  
    19.     void OnDisable()
    20.     {
    21.         inputMap.Disable();
    22.     }
    23. }
     
  6. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    525
    I see, I'm curious of this flag, here is the associated doc for anyone coming after : https://docs.unity3d.com/Packages/c...manual/Controls.html?q=USE_OPTIMIZED_CONTROLS
     
  7. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,384