Search Unity

Jittery Movement in 2D game with Cinemachine

Discussion in '2D' started by Reetro_89, Apr 8, 2021.

  1. Reetro_89

    Reetro_89

    Joined:
    Mar 21, 2021
    Posts:
    4
    Hello am looking for help with smothing out 2D movement. Am using Cinemachine for the camera system though it seems to jitter even when using a basic follow camera. I've notice this jitter in both my parallax background and on my player character. Not both at once however the background jitter only happens when my cininmachine brain has been set to smart update. Anyother setting also makes the player jitter. I've link a video showing this.


    So what could be causing this?

    Things I've tried

    • Setting the player's rigidbody interpolate mode to interpolate
    • I've tried serveral parllax scripts all result in the same result
    • Using different update methods on the Cinimachine Brain and in my Parallax script
    Current Code for Parllax and Movement

    Player Controller

    Code (CSharp):
    1. using System.Collections;
    2. using Gameplay_Scripts;
    3. using Gameplay_Scripts.General_Components;
    4. using Status_Effect_System;
    5. using UnityEngine;
    6. using UnityEngine.InputSystem;
    7.  
    8. namespace Player_Scripts
    9. {
    10.     /// <summary>
    11.     /// Handles all player movement and player input
    12.     /// </summary>
    13.     public class PlayerController : MonoBehaviour
    14.     {
    15.         [Header("Movement Settings")]
    16.         [Tooltip("Amount of force added when the player jumps")]
    17.         public float jumpForce = 400f;
    18.         [Tooltip("How fast the player can run")]
    19.         public float runSpeed = 35f;
    20.         [Tooltip("How fast the player falls")]
    21.         public float fallspeed = 69;
    22.         [Tooltip("How much speed the player has in air")]
    23.         public float inAirSpeed = 69;
    24.         [Tooltip("How much to smooth out the movement")]
    25.         [Range(0, .3f)] [SerializeField] private float movementSmoothing = 0.05f;
    26.         [Tooltip("Whether or not a player can steer while jumping")]
    27.         [SerializeField] private bool hasAirControl = false;
    28.         [Tooltip("How fast the player accelerates")]
    29.         [SerializeField] private float playerAcceleration = 10f;
    30.         [SerializeField] private PlayerLegs myLegs;
    31.        
    32.         #region Local Vars
    33.         private Rigidbody2D myRigidbody2D = null;
    34.         private bool isFacingRight = true; // For determining which way the player is currently facing.
    35.         private Health hpComp;
    36.         private Vector3 currentVelocity = Vector3.zero;
    37.         private float defaultRunspeed = 0f;
    38.         #endregion
    39.  
    40.         #region Player Controls
    41.         private PlayerControls controls = null;
    42.         private float horizontalMove = 0f;
    43.         #endregion
    44.  
    45.         #region Player Components
    46.         //private Animator myAnimator = null;
    47.         private Health healthComponent = null;
    48.         private Rigidbody2D myRigidBody2D = null;
    49.         #endregion
    50.  
    51.         private void Awake()
    52.         {
    53.             myRigidbody2D = GetComponent<Rigidbody2D>();
    54.             hpComp = GetComponent<Health>();
    55.             myLegs = transform.GetComponentInChildren<PlayerLegs>();
    56.             defaultRunspeed = runSpeed;
    57.            
    58.             controls = new PlayerControls();
    59.  
    60.             healthComponent = GetComponent<Health>();
    61.             myRigidBody2D = GetComponent<Rigidbody2D>();
    62.  
    63.            
    64.  
    65.             controls.Player.Jump.started += OnJumpPressed;
    66.  
    67.             controls.Player.DebugButton.started += OnDebugPress;
    68.         }
    69.  
    70.         private void OnEnable()
    71.         {
    72.             controls.Player.Enable();
    73.         }
    74.  
    75.         private void OnDisable()
    76.         {
    77.             controls.Player.Disable();
    78.         }
    79.  
    80.         #region Input Actions
    81.         /// <summary>
    82.         /// Called when jump button is pressed
    83.         /// </summary>
    84.         /// <param name="context"></param>
    85.         private void OnJumpPressed(InputAction.CallbackContext context)
    86.         {
    87.             if (CanPlayerMove())
    88.             {
    89.                 Jump();
    90.             }
    91.         }
    92.         /// <summary>
    93.         /// Debug button
    94.         /// </summary>
    95.         /// <param name="context"></param>
    96.         private void OnDebugPress(InputAction.CallbackContext context)
    97.         {
    98.             Debug.Log(PlayerState.CurrentMiteCount);
    99.         }
    100.         #endregion
    101.  
    102.         #region Movement Functions
    103.         /// <summary>
    104.         /// Check for player movement input and gun input
    105.         /// </summary>
    106.         private void Update()
    107.         {
    108.             if (CanPlayerMove())
    109.             {
    110.                 CheckForMoveInput();
    111.             }
    112.         }
    113.         /// <summary>
    114.         /// Check for jump input if true set movement state to jumping
    115.         /// </summary>
    116.         private void FixedUpdate()
    117.         {
    118.             if (CanPlayerMove())
    119.             {
    120.                 Move(horizontalMove * Time.fixedDeltaTime, true);
    121.             }
    122.         }
    123.         /// <summary>
    124.         /// Check to see if there is any input from the player
    125.         /// </summary>
    126.         private void CheckForMoveInput()
    127.         {
    128.             if (healthComponent.IsCurrentlyDead) return;
    129.             horizontalMove = controls.Player.Movement.ReadValue<Vector2>().x;
    130.  
    131.             /*switch (transform.localEulerAngles.y >= 180)
    132.                 {
    133.                     case true:
    134.                         myAnimator.SetFloat("Speed", -horizontalMove);
    135.                         break;
    136.                     case false:
    137.                         myAnimator.SetFloat("Speed", horizontalMove);
    138.                         break;
    139.                 }*/
    140.  
    141.             if (horizontalMove == 0)
    142.             {
    143.                 //myAnimator.SetBool("Idle", true);
    144.             }
    145.             else
    146.             {
    147.                 //myAnimator.SetBool("Idle", false);
    148.             }
    149.         }
    150.         /// <summary>
    151.         /// Actually move the player based the move direction
    152.         /// </summary>
    153.         /// <param name="move"></param>
    154.         /// <param name="forceFlip"></param>
    155.         private void Move(float move,  bool forceFlip)
    156.         {
    157.             if (hpComp.IsCurrentlyDead) return;
    158.             //Check to see if player is in air and applies in air speed if the player is in the air and is jumping
    159.             if (myRigidbody2D.velocity.y < 0 || myRigidbody2D.velocity.y > 0 && !myLegs.IsGrounded)
    160.             {
    161.                 runSpeed = inAirSpeed;
    162.             }
    163.             else
    164.             {
    165.                 runSpeed = defaultRunspeed;
    166.             }
    167.             //only control the player if grounded or airControl is turned on
    168.             if (!myLegs.IsGrounded && !hasAirControl) return;
    169.             // Move the character by finding the target velocity
    170.             var velocity = myRigidbody2D.velocity;
    171.             Vector3 targetVelocity = new Vector2(move * runSpeed * playerAcceleration, velocity.y);
    172.                    
    173.             // And then smoothing it out and applying it to the character
    174.             myRigidbody2D.velocity = Vector3.SmoothDamp(velocity, targetVelocity, ref currentVelocity, movementSmoothing);
    175.  
    176.             // If the input is moving the player right and the player is facing left...
    177.             if (move > 0 && !isFacingRight && forceFlip)
    178.             {
    179.                 // ... flip the player.
    180.                 // Switch the way the player is labeled as facing.
    181.                 isFacingRight = !isFacingRight;
    182.  
    183.                 var transform1 = transform;
    184.                
    185.                 var rotation = transform1.rotation;
    186.                
    187.                 rotation = new Quaternion(rotation.x, 180f, rotation.z, 0f);
    188.                
    189.                 transform1.rotation = rotation;
    190.  
    191.                 //transform.SetPositionAndRotation();
    192.  
    193.                 //GeneralFunctions.FlipObject(gameObject);
    194.             }
    195.             // Otherwise if the input is moving the player left and the player is facing right...
    196.             else if (move < 0 && isFacingRight && forceFlip)
    197.             {
    198.                 // Switch the way the player is labeled as facing.
    199.                 isFacingRight = !isFacingRight;
    200.  
    201.                 var transform1 = transform;
    202.                
    203.                 var rotation = transform1.rotation;
    204.                
    205.                 rotation = new Quaternion(rotation.x, 0f, rotation.z, 0f);
    206.                
    207.                 transform1.rotation = rotation;
    208.  
    209.                 //GeneralFunctions.FlipObject(gameObject);
    210.             }
    211.         }
    212.         /// <summary>
    213.         /// Add Upward Velocity to make the player jump
    214.         /// </summary>
    215.         private void Jump()
    216.         {
    217.             if (!myLegs.IsGrounded) return;
    218.            
    219.             // Remove all force towards player
    220.             myRigidbody2D.angularVelocity = 0f;
    221.             myRigidbody2D.velocity = Vector2.zero;
    222.  
    223.             // Apply the actual jump force
    224.             myRigidbody2D.AddForce(new Vector2(0f, jumpForce));
    225.         }
    226.         /// <summary>
    227.         /// Called when player touches ground
    228.         /// </summary>
    229.         private void OnLanding()
    230.         {
    231.             //myAnimator.SetBool("IsJumping", false);
    232.         }
    233.         /// <summary>
    234.         /// Completely stop all current movement on player will also completely freeze all incoming movement then sleeps the player rigidbody
    235.         /// </summary>
    236.         public void StopMovement()
    237.         {
    238.             myRigidbody2D.angularVelocity = 0;
    239.             myRigidbody2D.velocity = Vector2.zero;
    240.             currentVelocity = Vector3.zero;
    241.  
    242.             myRigidbody2D.constraints = RigidbodyConstraints2D.FreezeAll;
    243.  
    244.             myRigidbody2D.Sleep();
    245.         }
    246.         /// <summary>
    247.         /// Will reset player movement and wake up the players rigidbody
    248.         /// </summary>
    249.         public void ResetMovement()
    250.         {
    251.             myRigidbody2D.WakeUp();
    252.  
    253.             myRigidbody2D.constraints = RigidbodyConstraints2D.None;
    254.  
    255.             myRigidbody2D.freezeRotation = true;
    256.         }
    257.         /// <summary>
    258.         /// Checks to see if player can currently move
    259.         /// </summary>
    260.         /// <returns></returns>
    261.         private bool CanPlayerMove()
    262.         {
    263.             return !ControlDisabled && !healthComponent.IsCurrentlyDead && !GeneralFunctions.IsConsoleOpen();
    264.         }
    265.         #endregion
    266.  
    267.         #region Properties
    268.         /// <summary>
    269.         /// Checks to see if the player is stunned
    270.         /// </summary>
    271.         public bool ControlDisabled { get; private set; } = false;
    272.         /// <summary>
    273.         /// Reference to the players box collider
    274.         /// </summary>
    275.         public BoxCollider2D MyBoxCollider { get; private set; } = null;
    276.         #endregion
    277.     }
    278. }
    Parllax Code - Used this script https://answers.unity.com/questions/551808/parallax-scrolling-using-orthographic-camera.html

    Parallax Camera
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace Map_Control_Scripts
    4. {
    5.     [ExecuteInEditMode]
    6.     public class ParallaxCamera : MonoBehaviour
    7.     {
    8.         public delegate void ParallaxCameraDelegate(float deltaMovement);
    9.         public ParallaxCameraDelegate ONCameraTranslate;
    10.         private float _oldPosition;
    11.  
    12.         private void Start()
    13.         {
    14.             _oldPosition = transform.position.x;
    15.         }
    16.  
    17.         public void LateUpdate()
    18.         {
    19.             if (transform.position.x == _oldPosition) return;
    20.  
    21.             var position = transform.position;
    22.             var delta = _oldPosition - position.x;
    23.  
    24.             ONCameraTranslate?.Invoke(delta);
    25.            
    26.             _oldPosition = position.x;
    27.         }
    28.     }
    29. }
    30.  
    Parallax Layer
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace Map_Control_Scripts
    4. {
    5.     [ExecuteInEditMode]
    6.     public class ParallaxLayer : MonoBehaviour
    7.     {
    8.         public float parallaxFactor;
    9.         public void Move(float delta)
    10.         {
    11.             var transform1 = transform;
    12.             var newPos = transform1.localPosition;
    13.             newPos.x -= delta * parallaxFactor;
    14.             transform1.localPosition = newPos;
    15.         }
    16.     }
    17. }
    18.  
    Parallax Background
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. namespace Map_Control_Scripts
    5. {
    6.     [ExecuteInEditMode]
    7.     public class ParallaxBackground : MonoBehaviour
    8.     {
    9.         public ParallaxCamera parallaxCamera;
    10.         private readonly List<ParallaxLayer> _parallaxLayers = new List<ParallaxLayer>();
    11.  
    12.         private void Start()
    13.         {
    14.             if (parallaxCamera == null)
    15.                 if (Camera.main is { })
    16.                     parallaxCamera = Camera.main.GetComponent<ParallaxCamera>();
    17.             if (parallaxCamera != null)
    18.                 parallaxCamera.ONCameraTranslate += Move;
    19.             SetLayers();
    20.         }
    21.  
    22.         private void SetLayers()
    23.         {
    24.             _parallaxLayers.Clear();
    25.             for (var i = 0; i < transform.childCount; i++)
    26.             {
    27.                 var layer = transform.GetChild(i).GetComponent<ParallaxLayer>();
    28.  
    29.                 if (layer == null) continue;
    30.  
    31.                 layer.name = "Layer-" + i;
    32.                 _parallaxLayers.Add(layer);
    33.             }
    34.         }
    35.  
    36.         private void Move(float delta)
    37.         {
    38.             foreach (var layer in _parallaxLayers)
    39.             {
    40.                 layer.Move(delta);
    41.             }
    42.         }
    43.     }
    44. }
    45.  
     
  2. Blejz43

    Blejz43

    Joined:
    Mar 4, 2020
    Posts:
    8
    Try putting the code from the Update funtion in your player controller script into the FixedUpdate. For me personally putting everything movement related into FixedUpdate solves the jitter.
     
  3. Reetro_89

    Reetro_89

    Joined:
    Mar 21, 2021
    Posts:
    4
    Ya that didn't work but thank you for the response I ended just switch from Cinemachine to Procamera 2D and that has fixed all my issues
     
    Blejz43 likes this.