Search Unity

Cinemachine Free Look in a 3rd person controller

Discussion in 'Cinemachine' started by Vallar, Apr 22, 2019.

  1. Vallar

    Vallar

    Joined:
    Oct 18, 2012
    Posts:
    177
    Hi all,

    I am trying to create a 3rd person controller with Cinemachine's Free Look camera (as stated in the title). Previously I was using my own camera system and when it came time for handling collisions I felt it might just be easier to use Cinemachine (given we are using it for a few other things in the game already).

    Anyway, I set the Free Look camera as I wanted. However when it comes to movement, the player doesn't move in the direction of the camera. So picture you rotated your camera around the target to look to its right. Then decided to move forward. I want the character to auto rotate and face that direction (i.e. camera direction = movement direction). Previous camera setup I had worked flawlessly. With Cinemachine I am having a hard time getting this to work.

    Anyone has any pointers on how do this? Below is my movement code:

    Code (CSharp):
    1.     [SerializeField] private float moveSpeed;
    2.     [SerializeField] private float turnSmoothTime = 0.02f;
    3.     [SerializeField] private float moveSmoothTime = 0.3f;
    4.     [SerializeField] private Transform cameraTransform;
    5.     private float turnSmoothVelocity;
    6.     private float moveSmoothVelocity;
    7.     private float currentSpeed;
    8.     private new Transform transform;
    9.     private PlayerAnimation animations;
    10.     private CharacterController controller;
    11.  
    12.     public void MovePlayer(Vector2 _direction)
    13.     {
    14.         currentSpeed = GetCurrentSpeed(_direction);
    15.  
    16.         Vector3 velocity = transform.forward * currentSpeed * _direction.magnitude;
    17.  
    18.         controller.Move(velocity * Time.deltaTime);
    19.  
    20.         animations.AnimateRunning(_direction.magnitude, moveSmoothTime);
    21.     }
    22.  
    23.  
    24.     public void Rotate(Vector2 _direction)
    25.     {
    26.         if (CanRotate(_direction))
    27.         {
    28.             float targetAngle = Mathf.Atan2(_direction.x, _direction.y) * Mathf.Rad2Deg +                                                      cameraTransform.eulerAngles.y;
    29.  
    30.             transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle,              ref turnSmoothVelocity, turnSmoothTime);
    31.         }
    32.     }
    I already tried a few changes and tweaks but nothing bared fruit. Any help is appreciated.
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,720
    The first thing to understand about CM vcams is that they want to control their own transforms procedurally. That means that when they have procedural positioning enabled, you can't manually set their positions or rotations.

    This means that you have to structure the objects in the character controller to work with this. If you're using a FreeLook targeting the player, that has to be a separate game object from the player. Don't parent one to the other. Then your controller's motion processor can have a script that queries the camera for its forward axis and applies it when the player moves.

    Alternatively, instead of the FreeLook you can take advantage of CM's features while still using your old controller script. Just replace the Camera in your script with a vcam having DoNothing in Aim and Body. That turns off the procedural positioning, so your script can drive the vcam's position. You can then add noise, collision, and the vcam will participate in CM blends, just like the procedural vcams.
     
    Noble-Woods likes this.
  3. Vallar

    Vallar

    Joined:
    Oct 18, 2012
    Posts:
    177
    I wasn't trying to change anything on the camera, just pull its Y rotation.

    This worked very well. You're a wizard Gregoryl. Thank you very much.
     
    Gregoryl likes this.
  4. RownWinner

    RownWinner

    Joined:
    Jun 5, 2019
    Posts:
    1
    Hi @Vallar . Did you ever manage to get the camera's Y rotation?
     
  5. Vallar

    Vallar

    Joined:
    Oct 18, 2012
    Posts:
    177
    I wasn't able to get it and ended up using a CInemachine Virtual Camera with "Nothing" in both Body and Aim.
     
  6. The_Nerd_Sherpa

    The_Nerd_Sherpa

    Joined:
    Dec 11, 2018
    Posts:
    57
    By "Aim" and "Body", I assume you're talking about "Follow" and "Look At"? If so, have you come across any tutorials or articles on how to do this? I might be able to figure it out on my own..... but this would save me hours/days of trial and error.

    Thanks in advance!
     
  7. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,720
    Just replace the "Camera" component with a "CinemachineVirtualCamera" component. "Aim" and "Body" refer to the dropdowns in the virtualcamera inspector. They should be set to "Do Nothing".
     
    ferverence likes this.
  8. The_Nerd_Sherpa

    The_Nerd_Sherpa

    Joined:
    Dec 11, 2018
    Posts:
    57
    Perfect! I'll give that a try. Thanks for the quick response!