I have a relatively simple character controller that uses rb.velocity to move the character, with the x velocity being set to a value that lerps between 0 and a target velocity based on an acceleration value. this normally works fine for me, but this time, the rigidbody would move fine when going right, but jitter like crazy when moving left. I managed to mitigate this slightly by turning up Lookahead smoothing on the cinemachine camera, but now there is another issue. the lookahead works as expected when moving right (because there is no jitter) but only looks ahead a very small amount when moving left. I will attach my character controller script below and a screenshot of my settings, but any advice would be much appreciated.
The script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerController : MonoBehaviour
{
float xInput;
[Header("Variables")]
public float BaseSpeed;
public float JumpHeight;
public float Acceleration;
public float AirAccel;
public float Decelleration;
public float gravityScale;
[SerializeField]
public GameObject JumpEffect;
[Header("References")]
//the top and bottom raycasts for the ledgegrab check
public GameObject LedgeGrabTop;
public GameObject LedgeGrabBottom;
//layer that ground is on
public LayerMask GroundLayer;
Rigidbody2D rb;
//bottom of player object
public GameObject GroundCheck;
public Animator Anims;
//particle effect when you jump
//Things to keep track of other things
//keep track of current player state
public enum PlayerState
{
running, jumping, crawling, onLedge
}
PlayerState state;
bool grounded;
bool Flipped;
float TargetXVel;
// Start is called before the first frame update
void Start()
{
//assign rigidbody
rb = GetComponent<Rigidbody2D>();
//remove later
state = PlayerState.running;
}
// Update is called once per frame
void Update()
{
//debug
Debug.Log("playerState = " + state + " grounded = " + grounded + " playerSpeed = " + rb.velocity.x);
//makes sure player is turned in direction of movement
if (state == PlayerState.running && xInput < 0)
{
Flipped = true;
}else if(state == PlayerState.running && xInput > 0)
{
Flipped = false;
}
if (Flipped == true)
{
transform.rotation = Quaternion.Euler(0, 180, 0);
}
else
{
transform.rotation = Quaternion.Euler(0, 0, 0);
}
//get inputs
xInput = Input.GetAxisRaw("Horizontal");
if(state == PlayerState.running || state == PlayerState.onLedge)
{
if(Input.GetButtonDown("Jump"))
{
Jump();
}
}
//check if grounded
grounded = Physics2D.OverlapCircle(GroundCheck.transform.position, 0.3f, GroundLayer);
//perform jump cutoff for variable jump height
if(state == PlayerState.jumping && rb.velocity.y > 0)
{
if(Input.GetButtonUp("Jump"))
{
rb.velocity = new Vector2(rb.velocity.x, 0);
}
}
//handle Player states
if (grounded)
{
state = PlayerState.running;
}
if(!grounded && onLedge() == false)
{
state = PlayerState.jumping;
}
//get ledge state
if(grounded == false && onLedge() == true)
{
state = PlayerState.onLedge;
}else
{
if (grounded)
{
state = PlayerState.running;
}
if (!grounded && onLedge() == false)
{
state = PlayerState.jumping;
}
}
if(state == PlayerState.onLedge)
{
rb.velocity = new Vector2(rb.velocity.x, 0);
rb.gravityScale = 0;
}else
{
rb.gravityScale = gravityScale;
}
}
//called every physics update
private void FixedUpdate()
{
TargetXVel = xInput * BaseSpeed;
if(state == PlayerState.running)
{
if (xInput != 0)
{
rb.velocity = new Vector2(Mathf.Lerp(rb.velocity.x, TargetXVel, Acceleration), rb.velocity.y);
}
else if (xInput == 0)
{
rb.velocity = new Vector2(Mathf.Lerp(rb.velocity.x, TargetXVel, Decelleration), rb.velocity.y);
}
}else if(state == PlayerState.jumping)
{
if (xInput != 0)
{
rb.velocity = new Vector2(Mathf.Lerp(rb.velocity.x, TargetXVel, AirAccel), rb.velocity.y);
}
else if (xInput == 0)
{
rb.velocity = new Vector2(Mathf.Lerp(rb.velocity.x, TargetXVel, AirAccel), rb.velocity.y);
}
}
}
private void Jump()
{
if(state == PlayerState.onLedge)
{
rb.transform.position += -transform.right * 0.5f;
}
rb.velocity = new Vector2(rb.velocity.x, 0);
rb.AddForce(Vector2.up * JumpHeight, ForceMode2D.Impulse);
Instantiate(JumpEffect, GroundCheck.transform.position, Quaternion.identity);
}
bool onLedge()
{
if (Physics2D.Raycast(LedgeGrabTop.transform.position, transform.right, 0.4f, GroundLayer) == false && Physics2D.Raycast(LedgeGrabBottom.transform.position, transform.right, 0.4f, GroundLayer) == true)
{
return true;
}
else
{
return false;
}
}
}
thanks in advance for any help