Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

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

Discussion in 'Scripting' started by SajevID, Aug 18, 2020.

  1. SajevID

    SajevID

    Joined:
    Nov 9, 2019
    Posts:
    8
    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:
    Code (CSharp):
    1. void Update()
    2. {
    3.     //Get Mouse movement Y and turn it into float, also rotates the player on the X axis
    4.     transform.Rotate(Vector3.up * Input.GetAxis("Mouse X") * Time.deltaTime * mouseSensitivityX);
    5.     verticalLookRotation += Input.GetAxis("Mouse Y") * Time.deltaTime * mouseSensitivityY;
    6.     verticalLookRotation = Mathf.Clamp(verticalLookRotation, -180f, 180f);
    7.        
    8.     //I'm really not sure of this rotation Quaternion and I feel like this is the major problem
    9.     Quaternion rotation = Quaternion.Euler(verticalLookRotation, transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.z);
    10.  
    11.     Vector3 negDistance = new Vector3(0.0f, 0.0f, -15f);
    12.     Vector3 position = rotation * negDistance + transform.position;
    13.  
    14.     cameraT.position = position;
    15.     cameraT.localEulerAngles = Vector3.left * verticalLookRotation;
    16. }
    And an image I made in the powerful MSPaint of what I need:
    Third Person Camera explanation.png
     
  2. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,492
  3. SajevID

    SajevID

    Joined:
    Nov 9, 2019
    Posts:
    8
  4. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,492
    It took me 3 years to solve, no wonder
     
  5. SajevID

    SajevID

    Joined:
    Nov 9, 2019
    Posts:
    8
    Oof, haha and I have 3 days to finish this project:DD
     
  6. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
    I had this bit lying around. I think it does what you need:

    Code (CSharp):
    1. public class OrbitCamera : MonoBehaviour
    2. {
    3.     public Transform orbitTransform;
    4.     public float maxFollowDistance = 3;
    5.     public float freeLookSensitivity = 3f;
    6.    
    7.     public void Update()
    8.     {
    9.         float newRotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * freeLookSensitivity;
    10.         float newRotationY = transform.localEulerAngles.x - Input.GetAxis("Mouse Y") * freeLookSensitivity;
    11.         var desiredRotation = new Vector3(newRotationY, newRotationX, 0f);
    12.         transform.localEulerAngles = desiredRotation;
    13.  
    14.         var followDistance =  maxFollowDistance;
    15.  
    16.         if (Physics.SphereCast(orbitTransform.position, .25f, -transform.forward, out RaycastHit hitInfo,
    17.             maxFollowDistance))
    18.         {
    19.             followDistance = Mathf.Clamp(followDistance,0, hitInfo.distance);
    20.         }
    21.        
    22.         var desiredPosition = orbitTransform.position - transform.forward *followDistance;
    23.         transform.position = desiredPosition;
    24.     }
    25. }
     
    Chorlezzio likes this.