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

Smooth follow camera keeping track of multiple target

Discussion in 'Scripting' started by pezz, Jan 7, 2013.

  1. pezz

    pezz

    Joined:
    Apr 29, 2011
    Posts:
    606
    Hi

    I am having a problem. I would like to make the smooth follow camera have multiple targets and zoom in and out to keep track of its targets.

    There will be no switching of targets, all targets should be in view at all time

    I am having problems coming up with the logic for doing this. How could I go about doing this?


    Any help is appreciated.

    Thanks,
     
  2. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    612
    hmm, never did this... but i would start this way:

    -given that your environment is top-down and your camera is unrotated ( x is left&right on the viewport, z is top and bottom)
    -get the the lowest and highest position.x value among the objects
    -get the the lowest and highest position.z value among the objects
    -the middle between those positions is your x and z value where your camera should be centered at
    -then calculate the distance to ground (zoom) of your camera:
    --based on the fov your distance would be equal to (zCenter-zMax) of the objects if your fov is 90
    --use z because fov is the vertical camera angle
    --if your fov is other than 90 you have to compensate for that, if its only 45 you would have to use 2*zCenter-zMax as camera height
    --be sure to clamp the minimum camera height at a reasonable level

    picture that could help :D
    $Untitled.png
    Code (csharp):
    1.  
    2. //the formulas after you found the min and max values:
    3. float xCenter = (xMax-xMin)/2F;
    4. float zCenter = (zMax-zMin)/2F;
    5.  
    6. float height = 90F/Camera.fieldOfView * zMax-zCenter * 1.2F
    7. //*1.2 to zoom out a bit farther then needed, the objects would be on the very edge if not
    8.  
    9. Vector3 unSmoothCameraPosition = new Vector3(xCenter, height, zCenter);
    10. cameraTransform.position = Vector3.Lerp(cameraTransform.position,unSmoothCameraPosition,Time.deltaTime*gm.cameraSmoothFactor);
    11.  
    if you are not top down however, forget everything i said :D
    if your camera is rotated use the a rotated localposition of an object with the same rotation as the camera or sin() cos() to calculate the referential to the camera
     
    Last edited: Jan 8, 2013
    Gladrioss likes this.
  3. cAyouMontreal

    cAyouMontreal

    Joined:
    Jun 30, 2011
    Posts:
    315
    A minor correction here, if someone else is interested to implement it on their project.
    You will have to change the way xCenter and zCenter are calculated, because right now it's not the real center, you should do something like this:

    Code (CSharp):
    1. float xCenter = xMin + (Mathf.Abs(xMax-xMin)/2F);
    2. float zCenter = zMin + (Mathf.Abs(zMax-zMin)/2F);
    Finally I added an offset on unSmoothCameraPosition to balance the fact that my camera was angled by 70 degrees.

    Cheers !
     
    Marrt likes this.
  4. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    612
    Thanks for correcting it, i actually never tested the code and wrote the whole comment in the office, also: MSpaint

    Subaeria looks stunning, did you apply the code to it?
     
  5. cAyouMontreal

    cAyouMontreal

    Joined:
    Jun 30, 2011
    Posts:
    315
    Thanks but no, actually I participated to the Global game jam this weekend, we made this game:
    http://globalgamejam.org/2016/games/idle-idol
    You can try it, you will see the camera moving like what you said :D

    On Subaeria we use a far more complicated camera system :-/
     
  6. BluHornet

    BluHornet

    Joined:
    Feb 23, 2015
    Posts:
    40
  7. cAyouMontreal

    cAyouMontreal

    Joined:
    Jun 30, 2011
    Posts:
    315
  8. oakshiro

    oakshiro

    Joined:
    Dec 9, 2008
    Posts:
    20
    Hi there, I managed to achieve it by using the script on the tanks tutorial and modifying the zoom method to match this...
    Code (CSharp):
    1.   private void Zoom()
    2.     {
    3.         // Find the required size based on the desired position and smoothly transition to that size.
    4.         float requiredSize = FindRequiredSize();
    5.         if (m_Camera.orthographic)
    6.         {
    7.             m_Camera.orthographicSize = Mathf.SmoothDamp(m_Camera.orthographicSize, requiredSize, ref m_ZoomSpeed, m_DampTime);
    8.         }
    9.         else
    10.         {
    11.             Vector3 newPos = transform.position;
    12.             newPos.y = (90f / m_Camera.fieldOfView) * requiredSize;
    13.             newPos.y = Mathf.SmoothDamp(transform.position.y, newPos.y, ref m_ZoomSpeed, m_DampTime);
    14.             transform.position = newPos;
    15.         }
    16.     }
    I must say my camera is looking straight to the floor, further calculations should be used if the camera has any other rotation