Why does my Unity 3D Player Character jump ahead of the Cinemachine camera every few seconds?

411 Views Asked by At

Problem:

When the Player Character is rolling and the camera is following, every 10-30 seconds there is a frame where the player character jumps ahead of the camera and then the next frame it's back to normal. It's hard to recreate this issue as it seems to happen completely at random. My terrain is just a Unity 3D Plain with no bumps in it and some prototyping objects strewn about.

Here's a video of the issue, fast forward to the 18 second mark: https://youtu.be/QxAY-Ko2JrQ

Setup:

  • The player is a ball that can freely rotate as it rolls using Lerped changes in velocity via player input.

  • There is a GameObject named "DollyPivot" that follows the players exact transform.position and is the follow target of my Cinemachine (Body: 3rd Person Follow no damping, Aim: Hard Look At) virtual camera so the camera doesn't rotate with the player.

  • Player input rotates "DollyPivot" which rotates the Cinemachine virtual camera and seems to work just fine.

Code:

I removed as much unnecessary code as possible, like code for other inputs and includes.

Player character:


public class Player_Controller : MonoBehaviour
{
    public Player_Input playerControls;
    public Transform T_CameraTransform;
    public Rotate_Dolly Camera_DollyPivot;

    // Move Variables
    public float f_MoveSpeed = 10;
    public float f_MoveSmooth = 0.2f;
    public float f_MaxSpeed = 40f;

    // Gravity
    public float f_Gravity = -9.81f;
    public float f_GroundedGravity = -0.05f;
    public float f_CurrentGravity;

    private Vector2 V2_MoveDirection;
    private Vector2 V2_CameraDirection;
    private Transform T_Player;
    private Rigidbody RB_Player;

    void Awake()
    {
        playerControls = new Player_Input();
        f_CurrentGravity = f_Gravity;
    }

    void Start()
    {
        RB_Player = GetComponent<Rigidbody>();
        T_Player = GetComponent<Transform>();
        SetupJumpVariables();
    }

    void Update()
    {
        V2_MoveDirection = playerControls.Player.Move.ReadValue<Vector2>();
        V2_CameraDirection = playerControls.Player.Look.ReadValue<Vector2>();
        Camera_DollyPivot.SetLookRotation(V2_CameraDirection.x, -V2_CameraDirection.y);
        b_IsGrounded = Physics.Raycast(transform.position, Vector3.down, 1f);
        HandleJump();
    }

    void FixedUpdate()
    {
        Move();
        HandleGravity();
    }

    private void Move()
    {
        // Get Camera Normalized Directional Vectors
        Vector3 V3_Forward = T_CameraTransform.forward;
        Vector3 V3_Right = T_CameraTransform.right;

        // Create direction-relative-input vectors
        Vector3 V3_ForwardRelativeVerticalInput = V2_MoveDirection.y * V3_Forward;
        Vector3 V3_RightRelativeVerticalInput = V2_MoveDirection.x * V3_Right;

        // Create and apply camera relative movement to the player
        Vector3 V3_CameraRelativeMovement = V3_ForwardRelativeVerticalInput + V3_RightRelativeVerticalInput;

        RB_Player.velocity = Vector3.Lerp(RB_Player.velocity, new Vector3(V3_CameraRelativeMovement.x * f_MoveSpeed * Time.deltaTime, f_CurrentGravity, V3_CameraRelativeMovement.z * f_MoveSpeed * Time.deltaTime), f_MoveSmooth);
    }

    void HandleGravity()
    {
        if (b_IsGrounded)
        {
            f_CurrentGravity = f_GroundedGravity * Time.deltaTime;
        } else {
            f_CurrentGravity += f_Gravity * Time.deltaTime;
        }
    }

    private void OnEnable()
    {
        playerControls.Enable();
    }

    private void OnDisable()
    {
        playerControls.Disable();
    }
}

DollyPivot GameObject (Cinemachine VCamera's follow target):

Handles player input as rotation to DollyPivot GameObject and in turn moves the camera.


public class Rotate_Dolly : MonoBehaviour
{
    public float f_Horizontal = 0f;
    public float f_Vertical = 0f;
    public float f_CameraSpeed = 2f;
    public float f_MinAngle = 40f;
    public float f_MaxAngle = 340f;

    private Transform T_Self;

    void Start()
    {
        T_Self = GetComponent<Transform>();
    }

    void FixedUpdate()
    {
        T_Self.rotation *= Quaternion.AngleAxis(f_Horizontal * f_CameraSpeed, Vector3.up);
        T_Self.rotation *= Quaternion.AngleAxis(f_Vertical * f_CameraSpeed, Vector3.right);

        var angles = T_Self.localEulerAngles;
        angles.z = 0;
        var angle = T_Self.localEulerAngles.x;

        if (angle > 180 && angle < f_MaxAngle)
        {
            angles.x = f_MaxAngle;
        }
        else if (angle < 180 && angle > f_MinAngle)
        {
            angles.x = f_MinAngle;
        }

        T_Self.localEulerAngles = angles;
    }

    public void SetLookRotation(float xRotation, float yRotation)
    {
        f_Horizontal = xRotation;
        f_Vertical = yRotation;
    }
}

Attached to DollyPivot to follow Player Character


public class Follow_Target : MonoBehaviour
{
    public float f_Smooth = 0.3f;
    public Transform T_Target;

    private Transform T_Self;

    void Start()
    {
        T_Self = GetComponent<Transform>();
    }

    void FixedUpdate()
    {
        T_Self.position = Vector3.Lerp(T_Self.position, T_Target.position, f_Smooth);
    }
}


I've been trying all sorts of things to get this to stop happening. Considering it is a very stripped down project there are only so many things I could think to try.

I've tried:

  1. Completely removing the DollyPivot and switching the Cinemachine VCam to Orbital Transposer that just follows the player directly.
  2. Moving everything into FixedUpdate() that I think should be in there.
  3. Adding Lerping/Smoothing to anything that deals with positioning/velocity.
  4. Adding, removing, and tweaking: Camera X and Y look at and follow damping, DollyPivot follow target smoothing, Lerping Player input movement velocities.
  5. Changing the max speeds of the Player Character to see if it was velocity related.
  6. Changing the player RigidBody interpolation mode to interpolate.

And probably other things I've forgotten about at this point.

I'm at a loss for what could be the problem, any help or insight would be greatly appreciated! Thank you!

0

There are 0 best solutions below