Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Cinemachine First or Third person camera for spherical movement

Discussion in 'Cinemachine' started by Mathalous, Jun 26, 2022.

  1. Mathalous


    Jul 5, 2018
    I'm working on a 3d game where the character can be aligned with various gravity directions. One situation is a large sphere. As the character moves around the sphere it is rotated such that down is always towards the center. Additionally, rotating the camera left to right will cause the player to face that direction. While first person is preferred, I can work with third person as well.

    My issue is with the up direction of the camera not being synced, even if override world up in the brain is set to the player's transform. The FreeLook vcam is the closest I can get to working, as it seems to rotate with the character's up direction, but it doesn't play well with the left and right aiming.
  2. gaborkb


    Unity Technologies

    Nov 7, 2019
    Have a look at our sample scene called "SphericalSurfaceFollow". This has a player moving on a sphere with two different camera setups. One is a transposer and composer (CM vcam1) and the other is a freelook (CM FreeLook1) in Cinemachine version 2.8.6.

    You can also create a new vcam, assign your player to the Follow field and add ThirdPersonFollow to the body component. This will create a ThirdPerson camera for you. You can modify this camera to be a first person by changing Shoulder Offset, Vertical Arm Length and Camera Distance (to 0 for example).

    To get our sample scenes, go to the package manager, click on Cinemachine, and on the right side you'll see Samples and a download button.
  3. Mathalous


    Jul 5, 2018
    Thanks for the help, I think my issue was using target lock on the freelook camera and coupling the rotation with both the movement and the camera direction.
  4. Mathalous


    Jul 5, 2018
    Alright, so I modified the SphericalSurfaceFollow's player script to always look towards the camera position and move relative to the camera direction. I then made a new virtual camera with a third person follow body with the player as the follow and lookat target. I chose FOV for the aim type, as I want the player to control the look direction. Everything works well until the player moves to the opposite side of the sphere. At that point the camera does not rotate properly to reflect the new up direction.
    Code (CSharp):
    1. var delta = inputManager.Player.Move.ReadValue<Vector2>();
    2.     Vector3 input = new Vector3(delta.x, 0, delta.y);
    3.     if (input.magnitude > 0) {
    4.       if(moveCameraDir)
    5.         input = Camera.main.transform.rotation * input;
    7.       if (input.magnitude > 0.001f) {
    8.         transform.position += input * (speed * Time.deltaTime);
    9.       }
    10.     }
    11.     if (rotatePlayer) {
    12.       float t = Cinemachine.Utility.Damper.Damp(1, rotationDamping, Time.deltaTime);
    13.       //Quaternion newRotation = Quaternion.LookRotation(input.normalized, transform.up);
    14.       Quaternion newRotation = Quaternion.LookRotation(Camera.main.transform.forward, transform.up);
    15.       transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, t);
    16.     }
  5. Gregoryl


    Unity Technologies

    Dec 22, 2016
    To make the POV work properly, try making the vcam a child of the player.
    Mathalous likes this.
  6. Mathalous


    Jul 5, 2018
    Thanks for the help. Parenting the vcam to the child led to other issues, namely rotating the player about its y axis would also rotate the camera. To get around this I made an empty with a script to sync itself to the player depending on how I want the camera to function. Leaving it below for anyone with similar problems.

    Code (CSharp):
    2. using UnityEngine;
    3. namespace Mathalous {
    4.   public class PositionSync : MonoBehaviour {
    5.     public GameObject other;
    6.     public Vector3 rotationOffset;
    7.     public Vector3 positionOffset;
    8.     [System.Flags]
    10.     [Sirenix.OdinInspector.EnumToggleButtons]
    11. #endif
    12.     public enum UpdateOptions{
    13.       Position = 1,
    14.       Up = 1 << 2,
    15.       Forward = 1 << 3,
    16.     }
    17.     public UpdateOptions updateOptions;
    18.     private void Update() {
    19.       if(updateOptions.HasFlag(UpdateOptions.Position))
    20.         this.transform.position = other.transform.position + positionOffset;
    21.       if (updateOptions.HasFlag(UpdateOptions.Up))
    22.         this.transform.up = other.transform.up;
    23.       if (updateOptions.HasFlag(UpdateOptions.Forward)) {
    24.         transform.rotation = other.transform.rotation * Quaternion.Euler(rotationOffset);
    25.       }
    26.     }
    27.   }
    28. }
    gaborkb and Gregoryl like this.