- Home /
Aquarium like camera
Hey there,
for a project I want to create a fishtank, that is as big as the screen it is displayed on. I mean scaling the playarea, like making it as wide and tall as the screen is, without rescaling the other objects. The fish should be always be around the same size.
As I want the Fish to be 3D and move in 3D space i can't use an orthographic camera. And I would want the fish to be able to get close to the "glass" anywhere on the screen without getting too much distortion. The problem is, that through the pyramid shaped frustum of the perspective camera, fish closer to the screen just vanish when they get out of the frustum even though, they didn't leave the screen on the horizontal axis, when i make the camera too wide.
Is there any smart way to setup my camera?
Thank you!
Answer by Eno-Khaon · Feb 11, 2019 at 02:24 AM
https://docs.unity3d.com/Manual/FrustumSizeAtDistance.html
With a little bit of tweaking and adjusting, you can ensure that the closest walls (i.e. left/right/top/bottom) of the tank hit right at the edges of the screen at a specific distance. From there, you'll have depth beginning at your choice of distance from the camera.
With that in mind, you would be able to position boundaries at each corner relative to the screen.
As an example of this:
// C#
// For a script attached to the main camera
// These Transforms (ideally, unit cubes) are named
// based on the idea of looking in
// from the missing side
public Transform leftWall;
public Transform rightWall;
public Transform floor;
public Transform ceiling;
public Transform backWall;
public float tankDepth = 5.0f;
public float distanceToTank = 10.0f;
// Based on a unit cube (1x1x1)
public float wallThickness = 1.0f;
void Start()
{
// camera parameters
Camera cam = GetComponent<Camera>();
Vector3 camPos = transform.position;
Vector3 up = transform.up;
Vector3 forward = transform.forward;
Vector3 right = transform.right;
// Camera frustum information, based on
// Distance To (Fish) Tank
float frustumHeight = 2.0f * distanceToTank * Mathf.Tan(cam.fieldOfView * 0.5f * Mathf.Deg2Rad);
float frustumWidth = frustumHeight * cam.aspect;
// Sizing keys for sides
float wallDepth = distanceToTank + (tankDepth * 0.5f);
float halfThickness = wallThickness * 0.5f;
float doubleThickness = wallThickness * 2.0f;
float halfHeight = frustumHeight * 0.5f;
float halfWidth = frustumWidth * 0.5f;
// ceiling and floor are extended beyond the
// frustum width to include the width of
// the left and right sides
ceiling.position = camPos + (up * (halfHeight * halfThickness)) + (forward * wallDepth);
ceiling.localScale = new Vector3(frustumWidth + doubleThickness, wallThickness, tankDepth);
ceiling.rotation = transform.rotation;
floor.position = camPos - (up * (halfHeight * halfThickness)) + (forward * wallDepth);
floor.localScale = new Vector3(frustumWidth + doubleThickness, wallThickness, tankDepth);
floor.rotation = transform.rotation;
rightWall.position = camPos + (right * (halfWidth + halfThickness)) + (forward * wallDepth);
rightWall.localScale = new Vector3(wallThickness, frustumHeight, tankDepth);
rightWall.rotation = transform.rotation;
leftWall.position = camPos - (right * (halfWidth + halfThickness)) + (forward * wallDepth);
leftWall.localScale = new Vector3(wallThickness, frustumHeight, tankDepth);
leftWall.rotation = transform.rotation;
// the back wall will extend to fit everything
// else for convenience in this example
backWall.position = camPos + (forward * (distance + tankDepth + halfThickness));
backWall.localScale = new Vector3(frustumWidth + doubleThickness, frustumHeight + doubleThickness, wallThickness);
backWall.rotation = transform.rotation;
}
With this setup, all you have to tweak are the tankDepth and distanceToTank values and the tank will resize itself accordingly.
Edit: Fixed some formatting
Or maybe he wants to do it the other way round and using a dolly zoom with the target at the front of the fish tank. That way he can simply move the camera backwards and still see the same area at the target distance. The further away the camera is, the less distortion you get and the further away the near clipping plane is. An orthographic camera essentially would be a perspective camera at infinite distance. For everyone who hasn't heard about the dolly zoom, have a look at this video
Hi,
I'm sorry for the late reply. I was kinda busy. Thank you guys.
@$$anonymous$$o-$$anonymous$$haon, your method works like a charm!
@Bunny83 I'm gonna try your method later today. Thank you very $$anonymous$$uch!