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

Resolved How to adjust camera local Y position in this script

Discussion in 'Scripting' started by RealMcCoyGames, Jul 24, 2021.

  1. RealMcCoyGames

    RealMcCoyGames

    Joined:
    Jul 23, 2018
    Posts:
    65
    I have this script from a brackeys tutorial. It basically moves and zooms the camera so that multiple targets are always on screen. It works out the center point of all targets using bounds, puts the camera there, then adds some offset.

    It works pretty well but I would like the camera to rotate upwards a tiny bit depending on how zoomed it is.

    I would also like for the camera's y position to decrease slightly depending on how zoomed in it is.

    Unfortunately I have absolutely no idea how to do that. Watched the tutorial 3 times and I understand what the code is doing, but I'm not sure how I can get some reference to how zoomed in it is and adjust rotation and y position based off that.

    Here's the tutorial, and I will put my code below. My code is slightly different to the tutorial code, instead of depth of field I'm using z axis.



    Code (CSharp):
    1. public List<Transform> targets;
    2.  
    3. public Vector3 offset;
    4. private Vector3 velocity;
    5. public float smoothTime;
    6.  
    7. public float minZoom;
    8. public float maxZoom;
    9. public float zoomLimiter;
    10. private Camera cam;
    11.  
    12. void Start() {
    13.     cam = GetComponent<Camera>();
    14. }
    15.  
    16. void LateUpdate() {
    17.  
    18.     if(targets.Count == 0) {
    19.         return;
    20.     }
    21.  
    22.     Move();
    23.     Zoom();
    24.  
    25. }
    26.  
    27. void Move() {
    28.  
    29.     Vector3 centerPoint = GetCenterPoint();
    30.  
    31.     Vector3 newPosition = centerPoint + offset;
    32.  
    33.     transform.position = Vector3.SmoothDamp(transform.position, newPosition, ref velocity, smoothTime);
    34.  
    35. }
    36.  
    37. Vector3 GetCenterPoint() {
    38.  
    39.     if (targets.Count == 1) {
    40.         return targets[0].position;
    41.     }
    42.  
    43.     var bounds = new Bounds(targets[0].position, Vector3.zero);
    44.     for (int i = 0; i < targets.Count; i++) {
    45.        
    46.         bounds.Encapsulate(targets[i].transform.position);
    47.  
    48.     }
    49.  
    50.     return bounds.center;
    51.  
    52. }
    53.  
    54. void Zoom() {
    55.  
    56.     float newZoom = Mathf.Lerp(maxZoom, minZoom, GetGreatestDistance() / zoomLimiter);
    57.  
    58.     Vector3 camLocalPos = new Vector3(cam.transform.localPosition.x, cam.transform.localPosition.y, Mathf.Lerp(cam.transform.localPosition.z, newZoom, Time.deltaTime));
    59.     cam.transform.localPosition = camLocalPos;
    60.  
    61. }
    62.  
    63. float GetGreatestDistance() {
    64.  
    65.     var bounds = new Bounds(targets[0].position, Vector3.zero) ;
    66.     for (int i = 0; i < targets.Count; i++)    {
    67.  
    68.         bounds.Encapsulate(targets[i].transform.position);
    69.  
    70.     }
    71.  
    72.     return bounds.size.x;
    73.  
    74. }
    Thanks
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    This would be a rotate, probably applied to a sub-transform only around the local X axis.

    This would be an offset, again probably applied to a sub-tranform localPosition.

    Now I know the tutorial named it "zoom" but technically it is a "dolly" when you move the camera in / out. Zoom is when you change the field of view of the camera. :)

    That said, what you need is a way to map the third term in this line:

    Code (csharp):
    1. float newZoom = Mathf.Lerp(maxZoom, minZoom, GetGreatestDistance() / zoomLimiter);
    to your own notion of "how much" you want.

    The third term is:

    Code (csharp):
    1. float alpha = GetGreatestDistance() / zoomLimiter;
    and from its use in Mathf.Lerp(), we can infer it goes from 0 to 1.

    You could use that third term value to drive your own Lerp() that goes from "the least up" to "the most up" or the "least rotated" to the "most rotated," whatever those values are.

    Then you would use the results of that Lerp() to adjust either your position vertically, or your rotation, or both.

    Another way is to raise the "regard point" of the camera, eg change how high the "look at this point" is on the camera.

    Camera stuff gets pretty tricky pretty quickly... have you considered just using Cinemachine from the Unity Package manager? It does a lot of stuff like this right out of box.
     
    RealMcCoyGames likes this.
  3. RealMcCoyGames

    RealMcCoyGames

    Joined:
    Jul 23, 2018
    Posts:
    65
    I have heard of it, when I first found the tutorial I was hoping that he was going to use it. But then just ended up implementing it this way.

    Think I'll take a look into cinemachine because although the camera looks pretty awesome atm there are occasions when it's not quite right. For example it struggles a bit with targets that are quite far away from each other on the Y axis.

    Thanks so much for your help!
     
    Kurt-Dekker likes this.