Search Unity

Resolved Cinemachine camera constantly spinning after plugging in PS4 controller via Bluetooth

Discussion in 'Input System' started by andypett, Oct 5, 2022.

  1. andypett

    andypett

    Joined:
    Jun 11, 2019
    Posts:
    14
    Hey,

    I am making a prototype game, and so far in the process everything was working as expected.
    Then I turned on a PS4 Dualshock 4 controller via Bluetooth (Windows 10 computer) and started my game in Unity (2021.3.5f1).

    Suddenly a bunch of weird stuff happened. The Input System was NOT compatible with the PS4 controller AT ALL. At least not the settings I've used. (I only had a generic Gamepad binding in my controller setup).

    I shut down the controller, but now the game started to behave weirdly. I rolled back my changes, going back to the last working version in Plastic SCM. However, this still does not work as the camera is now constantly rotating around the player. If I move the mouse, it will rotate correctly in the direction I want to, but as soon as my mouse is still, it starts rotating in the one direction again (always the same direction).

    I can't find anything in my code that would cause this, and I have completely removed all Gamepad bindings from the Input System, but the problem persists.

    Some settings:

    Input system:

    InputSystem.jpg

    Cinemachine

    Cinemachine.jpg

    CinemachineInputProvider.jpg

    PlayerFreeLookState (current active state):

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerFreeLookState : PlayerBaseState
    6. {
    7.     private readonly int FREE_LOOK_SPEED_HASH = Animator.StringToHash("FreeLookSpeed");
    8.     private readonly int FREE_LOOK_BLENDTREE_HASH = Animator.StringToHash("FreeLookBlendTree");
    9.     private const float ANIMATION_DAMP_TIME = 0.1f;
    10.  
    11.     public PlayerFreeLookState(PlayerStateMachine newStateMachine) : base(newStateMachine)
    12.     {
    13.     }
    14.  
    15.  
    16.     public override void Enter()
    17.     {
    18.         _stateMachine.Animator.CrossFadeInFixedTime(FREE_LOOK_BLENDTREE_HASH, ANIMATION_DAMP_TIME);
    19.         _stateMachine.InputReader.TargetEvent += OnTarget;
    20.         _stateMachine.InputReader.JumpEvent += OnJump;
    21.         _stateMachine.InputReader.AttackEvent += OnAttack;
    22.     }
    23.  
    24.     public override void Tick(float deltaTime)
    25.     {
    26.         Vector3 movement = CalculateMovement();
    27.         Move(movement * _stateMachine.FreeLookMoveSpeed, deltaTime);
    28.  
    29.         UpdateAnimation(deltaTime);
    30.        
    31.         FaceMovementDirection(movement, deltaTime);
    32.     }
    33.  
    34.  
    35.     public override void Exit()
    36.     {
    37.         _stateMachine.InputReader.TargetEvent -= OnTarget;
    38.         _stateMachine.InputReader.JumpEvent -= OnJump;
    39.         _stateMachine.InputReader.AttackEvent -= OnAttack;
    40.     }
    41.  
    42.  
    43.     private void UpdateAnimation(float deltaTime)
    44.     {
    45.         if (_stateMachine.InputReader.MovementValue == Vector2.zero)
    46.         {
    47.             _stateMachine.Animator.SetFloat(FREE_LOOK_SPEED_HASH, 0, ANIMATION_DAMP_TIME, deltaTime);
    48.             return;
    49.         }
    50.  
    51.         _stateMachine.Animator.SetFloat(FREE_LOOK_SPEED_HASH, 1, ANIMATION_DAMP_TIME, deltaTime);
    52.     }
    53.  
    54.  
    55.     private Vector3 CalculateMovement()
    56.     {
    57.         var forward = _stateMachine.MainCameraTransform.forward;
    58.         var right = _stateMachine.MainCameraTransform.right;
    59.  
    60.         forward.y = 0;
    61.         right.y = 0;
    62.  
    63.         forward.Normalize();
    64.         right.Normalize();
    65.  
    66.         return forward * _stateMachine.InputReader.MovementValue.y +
    67.             right * _stateMachine.InputReader.MovementValue.x;
    68.     }
    69.  
    70.  
    71.     private void FaceMovementDirection(Vector3 movement, float deltaTime)
    72.     {
    73.         if (movement == Vector3.zero) return;
    74.  
    75.         _stateMachine.transform.rotation = Quaternion.Lerp(
    76.             _stateMachine.transform.rotation,
    77.             Quaternion.LookRotation(movement),
    78.             deltaTime * _stateMachine.RotationSpeed);
    79.     }
    80.  
    81.  
    82.     private void OnTarget()
    83.     {
    84.         if (_stateMachine.Targeter == null || !_stateMachine.Targeter.SelectTarget()) return;
    85.         _stateMachine.SwitchState(new PlayerTargetingState(_stateMachine));
    86.     }
    87.  
    88.  
    89.     private void OnJump()
    90.     {
    91.         _stateMachine.SwitchState(new PlayerJumpingState(_stateMachine));
    92.     }
    93.  
    94.  
    95.     private void OnAttack()
    96.     {
    97.         _stateMachine.SwitchState(new PlayerAttackingState(_stateMachine, 0));
    98.     }
    99. }
    100.  
    PlayerBaseState (some of the methods called in PlayerFreeLookState lie here):

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public abstract class PlayerBaseState : State
    6. {
    7.     protected PlayerStateMachine _stateMachine;
    8.  
    9.     public PlayerBaseState(PlayerStateMachine newStateMachine)
    10.     {
    11.         _stateMachine = newStateMachine;
    12.     }
    13.  
    14.  
    15.     protected void Move(float deltaTime)
    16.     {
    17.         Move(Vector3.zero, deltaTime);
    18.     }
    19.  
    20.  
    21.     protected void Move(Vector3 motion, float deltaTime)
    22.     {
    23.         motion += _stateMachine.ForceReceiver.Movement;
    24.         _stateMachine.CharacterController.Move(motion * deltaTime);
    25.  
    26.         if (_stateMachine.CharacterController.velocity.y < -0.5f)
    27.         {
    28.             _stateMachine.SwitchState(new PlayerFallState(_stateMachine));
    29.             return;
    30.         }
    31.     }
    32.  
    33.  
    34.     protected void FaceTarget()
    35.     {
    36.         if (_stateMachine.Targeter.CurrentTarget == null) return;
    37.  
    38.         var direction = _stateMachine.Targeter.CurrentTarget.transform.position - _stateMachine.transform.position;
    39.         direction.y = 0f;
    40.  
    41.         _stateMachine.transform.rotation = Quaternion.LookRotation(direction);
    42.     }
    43.  
    44.  
    45.     protected void ReturnToLocomotion()
    46.     {
    47.         if (_stateMachine.Targeter.CurrentTarget != null)
    48.         {
    49.             _stateMachine.SwitchState(new PlayerTargetingState(_stateMachine));
    50.         } else
    51.         {
    52.             _stateMachine.SwitchState(new PlayerFreeLookState(_stateMachine));
    53.         }
    54.     }
    55. }
    56.  
    InputReader (getting input from the Input System):

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.InputSystem;
    6.  
    7. public class InputReader : MonoBehaviour, Controls.IPlayerActions, Controls.IFallingActions
    8. {
    9.     public Vector2 MovementValue { get; private set; }
    10.     public Vector2 LookValue { get; private set; }
    11.     public event Action JumpEvent;
    12.     public event Action DodgeEvent;
    13.     public event Action TargetEvent;
    14.     public event Action CancelTargetEvent;
    15.     public event Action ResetCameraEvent;
    16.     public event Action AttackEvent;
    17.     public event Action PauseEvent;
    18.  
    19.     //public bool IsAttacking { get; private set; }
    20.     public bool IsBlocking { get; private set; }
    21.     public bool IsFlying { get; private set; }
    22.     private Controls _controls;
    23.  
    24.     void Start()
    25.     {
    26.         _controls = new Controls();
    27.         _controls.Player.SetCallbacks(this);
    28.  
    29.         _controls.Player.Enable();
    30.         _controls.Falling.SetCallbacks(this);
    31.         //_controls.Falling.Enable();
    32.     }
    33.  
    34.  
    35.     private void OnDestroy()
    36.     {
    37.         _controls.Player.Disable();
    38.         _controls.Falling.Disable();
    39.     }
    40.  
    41.  
    42.     public void OnJump(InputAction.CallbackContext context)
    43.     {
    44.         if (!context.performed) return;
    45.        
    46.         JumpEvent?.Invoke();
    47.     }
    48.  
    49.     public void OnDodge(InputAction.CallbackContext context)
    50.     {
    51.         if (!context.performed) return;
    52.  
    53.         DodgeEvent?.Invoke();
    54.     }
    55.  
    56.     public void OnMove(InputAction.CallbackContext context)
    57.     {
    58.         //if (context.canceled)
    59.         //    MovementValue = Vector2.zero;
    60.         //else
    61.         //    MovementValue = context.ReadValue<Vector2>();
    62.         MovementValue = context.ReadValue<Vector2>();
    63.     }
    64.  
    65.     public void OnLook(InputAction.CallbackContext context)
    66.     {
    67.         LookValue = context.ReadValue<Vector2>();
    68.     }
    69.  
    70.     public void OnTarget(InputAction.CallbackContext context)
    71.     {
    72.         if (!context.performed) return;
    73.  
    74.         TargetEvent?.Invoke();
    75.     }
    76.  
    77.     public void OnCancelTarget(InputAction.CallbackContext context)
    78.     {
    79.         if (!context.performed) return;
    80.  
    81.         CancelTargetEvent?.Invoke();
    82.     }
    83.  
    84.     public void OnAttack(InputAction.CallbackContext context)
    85.     {
    86.         //if (context.performed)
    87.         //    IsAttacking = true;
    88.         //else if (context.canceled)
    89.         //    IsAttacking = false;
    90.         if (!context.performed) return;
    91.  
    92.         AttackEvent?.Invoke();
    93.     }
    94.  
    95.     public void OnBlock(InputAction.CallbackContext context)
    96.     {
    97.         if (context.performed)
    98.             IsBlocking = true;
    99.         else if (context.canceled)
    100.             IsBlocking = false;
    101.     }
    102.  
    103.     public void OnResetCamera(InputAction.CallbackContext context)
    104.     {
    105.         if (!context.performed) return;
    106.  
    107.         ResetCameraEvent?.Invoke();
    108.     }
    109.  
    110.     public void OnPause(InputAction.CallbackContext context)
    111.     {
    112.         if (!context.performed) return;
    113.  
    114.         PauseEvent?.Invoke();
    115.     }
    116.  
    117.     public void OnFly(InputAction.CallbackContext context)
    118.     {
    119.         if (context.performed)
    120.             IsFlying = true;
    121.         else if (context.canceled)
    122.             IsFlying = false;
    123.     }
    124. }
    125.  
     
  2. andypett

    andypett

    Joined:
    Jun 11, 2019
    Posts:
    14
    Shortly after posting this, I realized that I hadn't actually verified the input.
    I found out that the Cinemachine Input Provider was using the wrong Input Action Reference. I have no idea why this changed.

    I switched it back to my own Input Actions and now it works perfectly fine.