Spherical Third-Person camera movement around the player character in 3D space

Hi, I’m making a third-person space game where the player jumps on planets and orients itself in full 3D space. I have a camera that is a child object of the player, positioned some distance back and can look up and down based on mouse Y input. However, it works as a first-person camera so when the player moves the camera up or down, the player is not visible anymore. What I want and what I’m trying to do instead is to have the camera always orient itself to look at the player and move in this locked spherical movement only around the Y-axis around the player.

This is the code that I have now, but it just doesn’t seem to work properly. As the camera only barely moves around in the general direction but doesn’t keep up with the player.

Code attached to the player:

void Update()
{
    //Get Mouse movement Y and turn it into float, also rotates the player on the X axis
    transform.Rotate(Vector3.up * Input.GetAxis("Mouse X") * Time.deltaTime * mouseSensitivityX);
    verticalLookRotation += Input.GetAxis("Mouse Y") * Time.deltaTime * mouseSensitivityY;
    verticalLookRotation = Mathf.Clamp(verticalLookRotation, -180f, 180f);
        
    //I'm really not sure of this rotation Quaternion and I feel like this is the major problem
    Quaternion rotation = Quaternion.Euler(verticalLookRotation, transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.z);

    Vector3 negDistance = new Vector3(0.0f, 0.0f, -15f);
    Vector3 position = rotation * negDistance + transform.position;

    cameraT.position = position;
    cameraT.localEulerAngles = Vector3.left * verticalLookRotation; 
}

And an image I made in the powerful MSPaint of what I need:

Not gonna lie, I read through it, but I don’t really get it

It took me 3 years to solve, no wonder

Oof, haha and I have 3 days to finish this project:smile:D

I had this bit lying around. I think it does what you need:

public class OrbitCamera : MonoBehaviour
{
    public Transform orbitTransform;
    public float maxFollowDistance = 3;
    public float freeLookSensitivity = 3f;
   
    public void Update()
    {
        float newRotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * freeLookSensitivity;
        float newRotationY = transform.localEulerAngles.x - Input.GetAxis("Mouse Y") * freeLookSensitivity;
        var desiredRotation = new Vector3(newRotationY, newRotationX, 0f);
        transform.localEulerAngles = desiredRotation;

        var followDistance =  maxFollowDistance;

        if (Physics.SphereCast(orbitTransform.position, .25f, -transform.forward, out RaycastHit hitInfo,
            maxFollowDistance))
        {
            followDistance = Mathf.Clamp(followDistance,0, hitInfo.distance);
        }
       
        var desiredPosition = orbitTransform.position - transform.forward *followDistance;
        transform.position = desiredPosition;
    }
}
1 Like