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

Scale camera / FOV to fit all players in view

Discussion in 'Scripting' started by SD2020_, Feb 12, 2018.

  1. SD2020_

    SD2020_

    Joined:
    Nov 3, 2015
    Posts:
    107
    Hi there,

    I have a script that allows me to track the centre point of all players in my scene(4 players, perspective camera).
    But when one player moves to far it goes completely off the screen, does anyone have a way of scaling the camera to fit all players into view with my current script?

    Here is my script:
    Code (CSharp):
    1. public class CameraControl : MonoBehaviour
    2. {
    3.     public List<Transform> Targets;
    4.     public Vector3 brickPosition = new Vector3(10, 0, 0);
    5.     private Vector3 _MiddlePoint;
    6.  
    7.     void Update()
    8.     {
    9.         _MiddlePoint = GetAveragePos(Targets);  
    10.         FollowTargets();
    11.     }
    12.  
    13.     public virtual void FollowTargets()
    14.     {
    15.         Vector3 dir = (Camera.main.transform.position - _MiddlePoint).normalized;
    16.         Vector3 averagePos = GetAveragePos(Targets);
    17.         transform.position = averagePos + brickPosition;
    18.     }
    19.  
    20.     protected virtual Vector3 GetAveragePos(List<Transform> targets)
    21.     {
    22.         Vector3 averagePos = Vector3.zero;
    23.         Vector3[] positions = new Vector3[targets.Count];
    24.         for (int i = 0; i < targets.Count; i++)
    25.         {
    26.             positions[i] = targets[i].transform.position;
    27.             averagePos += positions[i];
    28.         }
    29.         return averagePos / positions.Length;
    30.     }
    31. }
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    You might be able to try a combination of OnBecameInvisible/Visible and adjust the camera distance or FOV (if you prefer).
    If 1 or more is not visible, then modify (whichever) gradually until they all are.

    I never liked FoV for zooming, personally, but that was way back when I first started.
     
  3. SD2020_

    SD2020_

    Joined:
    Nov 3, 2015
    Posts:
    107
    Not a fan of the FOV zooming myself, im looking to transform the position of the camera instead.
     
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Ya, perhaps try the same idea and move the position until all are visible.
     
  5. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
  6. SD2020_

    SD2020_

    Joined:
    Nov 3, 2015
    Posts:
    107
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I have no idea if there's better math to work this out, but for fun I wrote something up..
    I am sure it can be improved, and possibly modified if it doesn't fit your game design, but perhaps it will be helpful :) Was kinda fun.
    Code (csharp):
    1.  
    2. public Transform cam;
    3.     public Transform[] targets;
    4.     [SerializeField]
    5.     int bufferOut = 100;
    6.     [SerializeField]
    7.     int bufferIn = 140;
    8.     void Update()
    9.     {
    10.         bool outside = false;
    11.         Vector3 vp = Vector3.zero;
    12.         for(int i = 0; i < targets.Length; ++i)
    13.         {
    14.             if (targets[i].GetComponent<Renderer>().isVisible)
    15.             {
    16.                 vp = Camera.main.WorldToScreenPoint(targets[i].position);
    17.                 if(vp.x < bufferOut || vp.x > Screen.width - bufferOut || vp.y < bufferOut || vp.y > Screen.height - bufferOut)
    18.                 {
    19.                     outside = true;
    20.                     break;
    21.                 }
    22.                 continue;
    23.             }
    24.             outside = true;
    25.             break;
    26.         }
    27.         if (outside)
    28.         {
    29.             cam.transform.position -= new Vector3(0, 0, 7) * Time.deltaTime;
    30.         }
    31.         else
    32.         {
    33.             int countIn = 0;
    34.             int cnt = targets.Length;
    35.             for(int i = 0; i < cnt; ++i)
    36.             {
    37.                 vp = Camera.main.WorldToScreenPoint(targets[i].position);
    38.                 if (vp.x > bufferIn && vp.x < Screen.width - bufferIn && vp.y > bufferIn && vp.y < Screen.height - bufferIn) ++countIn;
    39.             }
    40.             if(countIn == cnt)
    41.                 cam.transform.position += new Vector3(0, 0, 7) * Time.deltaTime;
    42.         }
    43.     }
     
  8. SD2020_

    SD2020_

    Joined:
    Nov 3, 2015
    Posts:
    107
    Thanks for the help man, with a little bit more sleepless nights I managed to write a camera controller using perspective view :)