0
\$\begingroup\$

I'm trying to solve this 'algorithm' problem.

I have a player and a camera on it. I want to automatically move this player towards a target object and stop it when target object completely "fit" my camera.

So my question is : how can I find target Vector3 player position, and camera rotation (up/down) to perfectly "view" an object ?

Consider that my target objects are simple Box.

Thanks

Edit: X is the "right" transform.position to "full" see target object

enter image description here

\$\endgroup\$
4
  • \$\begingroup\$ What does your code know about the shape or bounds of the object? \$\endgroup\$
    – DMGregory
    Commented Feb 5, 2021 at 22:46
  • \$\begingroup\$ My code know object and these object are simple: square or rectangle !! \$\endgroup\$
    – stighy
    Commented Feb 5, 2021 at 23:07
  • \$\begingroup\$ As in they're 2D objects with a SpriteRenderer or a BoxCollider2D? \$\endgroup\$
    – DMGregory
    Commented Feb 5, 2021 at 23:18
  • \$\begingroup\$ No , 3d object, and yes, i can put boxcollider \$\endgroup\$
    – stighy
    Commented Feb 5, 2021 at 23:36

1 Answer 1

2
\$\begingroup\$

Disclaimer: I don't use Unity or C#. All Unity-specific information was obtained from the documentation and not tested.

The field of view angle (FOV) determines the ratio of an object's size to its distance from the camera.

First, take the FOV and divide it by 2 (to get the angle from center rather than edge-to-edge, which is necessary by the next step) and, if it is in degrees, convert it to radians.

Then take the tangent of the angle. The tangent function tells us the slope — the ratio of distance to sideways movement — corresponding to the angle. (Another interpretation of this is “if an object is 1 unit away from the camera, how big will it be on screen?”)

Then, take the size of the object in terms of its radius or the maximum distance from its origin to an edge (supposing that you want the object to be as big as possible while still fitting in the camera's frame), and divide it by the tangent.

float targetCameraDistance =
  objectRadius / Mathf.Tan(fovDegrees * (Mathf.Deg2Rad / 2));

Now you know how far away the camera should be and you can steer it there.


Note that since screens are not square or circular, this will only perfectly fit the object in one dimension, unless the object has the same aspect ratio as the screen. Instead, the screen effectively has two FOV values — horizontal and vertical.

How you handle this will depend on how you intend your game's UI to scale to different screen aspect ratios, but a place to start is Unity's VerticalToHorizontalFieldOfView (and the corresponding vertical to horizontal conversion if needed).

  • Simple case: If you want to the object to fit within the screen bounds, and your FOV is defined as a vertical FOV and your aspect ratio is always wider than tall, then you can just use the vertical FOV to get a perfect fit.
  • If you want the object to fit within and you allow free window resizing so it might be taller than wide, you need to use whichever of the vertical or horizontal FOV is smaller.
  • If you want the object to completely fill the screen (no pixel left uncovered), then you need to think about what size will fill the corners of the screen. That size will depend on the shape of the object, and the aspect ratio of the screen.
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .