Cinemachine problems with first person controller

Hello to everyone! I am writing a first person player controller and I am facing some problems with cinemachine (however, it may be general problems with engine usage). Both methods below (Move and Rotate) are called from Update() method.

My cinemachine camera does not keep up with the movement of transform its attached on If it moves too fast (I am using CharacterController’s Move method). Here are my cinemachine settings, moving method and how it looks (on capsule collider):

private void Move(Vector2 movingVector)
{
    Vector3 inputDirection = transform.right * movingVector.x +
                          transform.forward * movingVector.y;
 
    Vector3 motion = inputDirection * movementSpeed *
                     _currentRunMultiplier * Time.deltaTime;
                   
    _characterController.Move(motion);  
}

My second problem is twitching camera on rotation. I am using following method for rotating camera and it sometimes (it randomly depends on restarting the editor lol) twitches camera during the rotation.

private void Rotate(Vector2 rotationVector)
{
    if (rotationVector.sqrMagnitude < _rotationThreshold) return;

    rotationVector *= rotationSpeed * Time.deltaTime;
   
    _verticalRotation = Mathf.Clamp(rotationVector.y + _verticalRotation,
        _minVerticalRotation, _maxVerticalRotation);
   
    Vector3 headRotation = Vector3.right * _verticalRotation;
    Vector3 bodyRotation = Vector3.up * rotationVector.x;
   
    _headTransform.localRotation = Quaternion.Euler(headRotation);
    transform.Rotate(bodyRotation);
}

However, if I use coroutine for rotation following way, reacting on input manager:

private void StartRotating()
{
    if (_rotationCoroutine != null) StopCoroutine(_rotationCoroutine);
    _rotationCoroutine = Rotate();
    StartCoroutine(_rotationCoroutine);
}

private IEnumerator Rotate()
{
    while (_inputManager.rotation.Value != Vector2.zero)
    {
        Rotate(_inputManager.rotation.Value);
       
        yield return null;
    }
}

private void Rotate(Vector2 rotationVector)
{
    if (rotationVector.sqrMagnitude < _rotationThreshold) return;

    rotationVector *= rotationSpeed * Time.deltaTime;
   
    _verticalRotation = Mathf.Clamp(rotationVector.y + _verticalRotation,
        _minVerticalRotation, _maxVerticalRotation);
   
    Vector3 headRotation = Vector3.right * _verticalRotation;
    Vector3 bodyRotation = Vector3.up * rotationVector.x;
   
    _headTransform.localRotation = Quaternion.Euler(headRotation);
    transform.Rotate(bodyRotation);
}

It also twitches, but much harder. Sometimes it vice versa rotating too slow. What am I doing wrong?

You CM setup is wrong. You need separate game objects, not parented to each other:

  • A Unity Camera game object with a CM Brain component
  • Your character controller that moves and rotates on user input
  • A CM virtual camera with a 3rdPerson setup, with the follow target being your character controller.

See the AimingRig sample scene in the Cinemachine samples. You can also follow this tutorial:

1 Like

Thanks for your reply!

I put them together only for screenshot, they are separated in my scene. Here is my hierarchy and those components:

7572994--937894--cameras.png

AimingRig scene is using old input system, whereas I use new one. I am using starter assets` first person controller as reference, and my controller has almost the same business logic, but there is like some fundamental problem.

By the way, calling Rotate method from LateUpdate removes camera twitching. My friend helped me, It is a shame I did not find it by myself.

But I am still facing problem with virtual camera not keeping up with its following target’s speed. By the way, default camera keeps up with the character controller`s movement (while cinemachine vitrual camera is not).

Did you try setting the Damping to 0?

1 Like

Thank you very much! You helped me a lot!

1 Like