Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Free Look with new input system?

Discussion in 'Cinemachine' started by Knightmore, May 12, 2019.

  1. Knightmore

    Knightmore

    Joined:
    May 11, 2012
    Posts:
    227
    Hey there,
    has anybody already got cinemachine free look to work with the new input system?

    I can't find any good solution to pass the mouse movement like with the old input system. I always end up with some ugly code and a wonky camera movement as it seems, that It nearly always triggers the Y-movement and only some of the time the X-movement.

    Code (CSharp):
    1. [RequireComponent(typeof(CinemachineFreeLook))]
    2.     public class CinemachineNewInputFreeLook : MonoBehaviour
    3.     {
    4.         private PlayerControls controls;
    5.         private float x;
    6.         private float y;
    7.  
    8.         public void Awake()
    9.         {
    10.             controls = new PlayerControls();
    11.             CinemachineCore.GetInputAxis = GetAxisCustom;
    12.         }
    13.  
    14.         public void OnEnable()
    15.         {
    16.             controls.ThirdPersonController.MouseCameraMovement.performed += CameraMovement;
    17.             controls.ThirdPersonController.MouseCameraMovement.Enable();
    18.         }
    19.  
    20.         public void OnDisable()
    21.         {
    22.             controls.ThirdPersonController.MouseCameraMovement.performed -= CameraMovement;
    23.             controls.ThirdPersonController.MouseCameraMovement.Disable();
    24.         }
    25.  
    26.         public float GetAxisCustom(string axisName)
    27.         {
    28.             if (axisName == "Mouse X")
    29.             {
    30.                 var tempX = x;
    31.                 x = 0;
    32.                 return tempX;
    33.             }
    34.             else if (axisName == "Mouse Y")
    35.             {
    36.                 var tempY = y;
    37.                 y = 0;
    38.                 return tempY;
    39.             }
    40.  
    41.             return 0;
    42.         }
    43.  
    44.         public void CameraMovement(InputAction.CallbackContext context)
    45.         {
    46.             var delta = context.ReadValue<Vector2>();
    47.             x = ClampValue(delta.x);
    48.             y = ClampValue(delta.y);
    49.         }
    50.  
    51.         public float ClampValue(float delta)
    52.         {
    53.             if (delta <= -1)
    54.                 return -1;
    55.             else if (delta >= 1)
    56.                 return 1;
    57.             else
    58.                 return delta;
    59.         }
    60.     }
    Input Mapping is inside the attached screenshot.

    upload_2019-5-12_20-1-10.png
     
    ManjitSBedi and Windroid like this.
  2. imnezaki

    imnezaki

    Joined:
    Aug 30, 2019
    Posts:
    1
    This gets mouse rotation and then apply it to camera :

    Code (CSharp):
    1. float  HorizontalSensitivity  = 30.0f;
    2. float  VerticalSensitivity  = 30.0f;
    3.  
    4. float RotationX = HorizontalSensitivity * this.InputsManager.MouseX * Time.deltaTime;
    5. float RotationY = VerticalSensitivity * this.InputsManager.MouseY * Time.deltaTime;
    6.  
    7. Vector3 CameraRotation = Camera.transform.rotation.eulerAngles;
    8.  
    9. CameraRotation.x -= RotationY;
    10. CameraRotation.y += RotationX;
    11.  
    12. Camera.transform.rotation = Quaternion.Euler(CameraRotation);
    Input Asset :



    InputsManager.cs :

    Code (CSharp):
    1. public void OnRotationX(InputAction.CallbackContext Context)
    2.     {
    3.         MouseX = Context.ReadValue<float>();
    4.     }
    5.  
    6.     public void OnRotationY(InputAction.CallbackContext Context)
    7.     {
    8.         MouseY = Context.ReadValue<float>();
    9.     }
     
  3. Hellzbellz123

    Hellzbellz123

    Joined:
    May 15, 2019
    Posts:
    12
    i did this same exact thing using the new input system with this code
    Code (CSharp):
    1.     public class CameraManager : MonoBehaviour
    2.     {
    3.         private DefaultControls defaultcontrols; //default controls is just the Csharp code you generate from the action maps asset
    4.         private Vector2 LookDelta;
    5.         public bool Lockon; //this would be used to switch to a virtual camera for a lockon system
    6.  
    7.         private void Awake() => defaultcontrols = new DefaultControls();
    8.  
    9.         private void OnEnable() => defaultcontrols.TPController.Enable();
    10.         private void OnDisable() => defaultcontrols.TPController.Disable();
    11.  
    12.         private void Update()
    13.         {
    14.             CinemachineCore.GetInputAxis = GetAxisCustom;
    15.         }
    16.  
    17.         public float GetAxisCustom(string axisName)
    18.         {
    19.             LookDelta = defaultcontrols.TPController.Camera.ReadValue<Vector2>(); // reads theavailable camera values and uses them.
    20.             LookDelta.Normalize();
    21.  
    22.             if (axisName == "Mouse X")
    23.             {
    24.                 return LookDelta.x;
    25.             }
    26.             else if (axisName == "Mouse Y")
    27.             {
    28.                 return LookDelta.y;
    29.             }
    30.             return 0;
    31.         }
    32.     }
    then all you have to do is MAKE SURE that whatever is controlling your Camera action is set as Value/Vector (i beat my head against a wall for 3 days bc of this)
     

    Attached Files:

    Gandarufu and Gregoryl like this.
  4. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    Are there plans for official compatibility between Cinemachine and the the new Input System?
     
  5. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    @Hellzbellz123 Thanks for that. Will this still work if I switch to a different action map? Or do I need to change the code to cater for that?
     
  6. Worstharbor

    Worstharbor

    Joined:
    Jan 29, 2020
    Posts:
    3
    Yea for some reason its not working for me? I have haven't added this as a component to any of my game objects does it go on camera?
     
  7. spiritworld

    spiritworld

    Joined:
    Nov 26, 2014
    Posts:
    29
    Sidenote: GetInputAxis is a delegate so no reason to assign it in Update loop. Once in Awake/Start should be enough
     
  8. Deleted User

    Deleted User

    Guest

    what does MouseX/Y and Inputmanagers mean?
     
  9. Ujjwal_Rajput

    Ujjwal_Rajput

    Joined:
    Jun 4, 2020
    Posts:
    5
    using the script given above unity giving error that you are using new new input system, so i made this script it is working ok with mouse position in key binding we can use even delta but i don't know how to make came look smoot.
    if anyone know how to solve it please improve this script
    Code (CSharp):
    1. using UnityEngine.InputSystem;
    2. using UnityEngine;
    3. using Cinemachine;
    4. public class CameraLook : MonoBehaviour
    5. {
    6.     PlayerInput playerInput;
    7.     CinemachineFreeLook cinemachineFreeLook;
    8.     private void Awake() {
    9.         playerInput = new PlayerInput();  // script created by new input system
    10.         cinemachineFreeLook = GetComponent<CinemachineFreeLook>();
    11.         playerInput.GroundInput.Camera.performed += CameraDelta;
    12.     }
    13.     void CameraDelta(InputAction.CallbackContext context) {
    14.         Vector2 LookDelta = context.ReadValue<Vector2>();
    15.         cinemachineFreeLook.m_XAxis.Value = LookDelta.x;
    16.         LookDelta.Normalize();
    17.         cinemachineFreeLook.m_YAxis.Value = LookDelta.y;
    18.     }
    19.     private void OnEnable() => playerInput.GroundInput.Enable();
    20.     private void OnDisable() => playerInput.GroundInput.Disable();
    21. }
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    @Ujjwal_Rajput It's because you're assigning to axis.Value. Instead, you should be modifying axis.m_InputAxisValue, and let the axis do the smoothing.

    However, Cinemachine now comes with native support for the new input system, so you can delete all this code and add a CinemachineInputProvider component to your FreeLook instead.
     
    Last edited: Sep 28, 2020
    igor-240340 and ManjitSBedi like this.
  11. Ujjwal_Rajput

    Ujjwal_Rajput

    Joined:
    Jun 4, 2020
    Posts:
    5
    thank you @Gregoryl , cinemachine input provider working great.
    can you please elaborate what is player index in input provider it said leave it -1 for single-player and set this to player index for multi-player it is about local multi-player or online multi-player?
     
    Last edited: Sep 29, 2020
    Gregoryl likes this.
  12. Ujjwal_Rajput

    Ujjwal_Rajput

    Joined:
    Jun 4, 2020
    Posts:
    5
    you can use cinemachine input provider component as @Gregoryl mentioned or if you still want to control it using script and mouse Delta you can use the script down blow.

    Code (CSharp):
    1. using UnityEngine.InputSystem;
    2. using UnityEngine;
    3. using Cinemachine;
    4.  
    5. public class CameraLook : MonoBehaviour
    6. {
    7.     PlayerInput playerInput;
    8.     CinemachineFreeLook cinemachineFreeLook;
    9.  
    10.     public float mouseSensivityX = 1;
    11.     public float mouseSensivityY = 1;
    12.  
    13.  
    14.     private void Awake() {
    15.         playerInput = new PlayerInput();  // script created by new input system
    16.         cinemachineFreeLook = GetComponent<CinemachineFreeLook>();
    17.         playerInput.GroundInput.Camera.performed += CameraDelta;
    18.     }
    19.  
    20.     private void Start() {
    21.         Cursor.visible = false;
    22.     }
    23.  
    24.     void CameraDelta(InputAction.CallbackContext context) {
    25.         Vector2 lookDelta = context.ReadValue<Vector2>();
    26.         cinemachineFreeLook.m_XAxis.Value -= lookDelta.x * mouseSensivityX;
    27.  
    28.         float lookDeltaY = lookDelta.y / 100f;
    29.         cinemachineFreeLook.m_YAxis.Value += lookDeltaY * mouseSensivityY;
    30.     }
    31.  
    32.    
    33.     private void OnEnable() => playerInput.GroundInput.Enable();
    34.  
    35.     private void OnDisable() => playerInput.GroundInput.Disable();
    36. }
    37.  
     
  13. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    This value is just passed directly to the input system. You can ask on the input system forum for more info on this.
     
    Ujjwal_Rajput likes this.
  14. rshea0

    rshea0

    Joined:
    Jul 23, 2023
    Posts:
    3
    Using the new CinemachineInputProvider doesn't work well for me when the input system is set to dynamic update.

    AxisState multiplies the input by deltaTime, but mouse input is already a delta. It seems Cinemachine is expecting the input system to be set to fixed update.
     
  15. antoinecharton

    antoinecharton

    Unity Technologies

    Joined:
    Jul 22, 2020
    Posts:
    189
    What happens if you add this processor to your input?
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.InputSystem;
    3. #if UNITY_EDITOR
    4. using UnityEditor;
    5. [InitializeOnLoad]
    6. #endif
    7. public class DeltaTimeProcessor : InputProcessor<Vector2>
    8. {
    9. #if UNITY_EDITOR
    10.     static DeltaTimeProcessor()
    11.     {
    12.         Initialize();
    13.     }
    14. #endif
    15.     [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    16.     static void Initialize()
    17.     {
    18.         InputSystem.RegisterProcessor<DeltaTimeProcessor>();
    19.     }
    20.     public override Vector2 Process(Vector2 value, InputControl control)
    21.     {
    22.         return value * Time.deltaTime;
    23.     }
    24. }
     
  16. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Probably you want to divide the value by deltaTime, not multiply it, since the desire is to cancel the built-in multiplication done by AxisState.
     
    antoinecharton likes this.