I can’t implement this for you without getting involved too much, but I can help with stepping stones

**first of all (1)**, you need Camera.CalculateFrustumCorners

check out the example to see how to use it.

frustum is the cut-off pyramid shape that’s cast by your camera (if you’re in perspective mode).

with this method, you get the four vectors (not points) that are assumed to originate from the camera position and go off precisely through the corners of your screen.

with these vectors (imagine them as rays) it’s now easy to compute where these rays will intersect with an imaginary plane that slices your cube in two halves (front and back).

to do this, first let’s assume that your cube’s pivot is exactly at its center. this is your cube’s position.

now you can define a plane from two information available: A) any point that belongs to it, B) a normal vector

this is the illustration for the normal vector

a point that belongs to it is your cube’s position, and a normal vector in your case, is practically `camera.transform.forward`

(or a negative of that to get an inverse), because you know that this plane is oriented exactly perpendicular to your eyesight.

finally, when you have a plane made with a `new Plane(...)`

, you can compute intersection by using the plane’s Raycast method

however, you now need to supply a Ray value to it. you can tell a ray if you know the following information: A) the origin of the ray, B) the direction of the ray.

the vectors you got from Camera.CalculateFrustumCorners are your directions, and the origin is your camera position.

now that you have the 4 intersecting points, let’s just call them **the frustum points**, and let’s move on to the second part.

**second of all (2)**, you have to make sure you have calculated how wide and tall your cube should be, in world units.

to do this you need a bit of geometry. because your cube is rotated the way it is, you actually want to compute the extents of the 2D bounding box surrounding it.

the easiest and the most versatile way to do this is to project all of its vertices back to your imaginary plane, and then you’ll get some coordinates that lie in 2D space, from which you can easily obtain the bounds.

*projecting* btw, means “finding some rays which pass through the cube vertices, then computing their intersection with the plane”

for example, if you know that your cube is exactly 2 units wide/tall/deep, and its center is in the middle of it, then its eight vertices are distributed like this

```
// upper half
0: -1, 1, -1
1: -1, 1, 1
2: 1, 1, 1
3: 1, 1, -1
// lower half
4: -1, -1, -1
5: -1, -1, 1
6: 1, -1, 1
7: 1, -1, -1
```

to make a ray for each vertex, you can find a vector between the vertex and camera position like this

```
Vector3 vec = camera.position - vertex[i];
```

now this is a full span. to make a unit direction out of it, you need to normalize this.

```
Vector3 dir = (camera.position - vertex[i]).normalized;
```

and now you can make a ray, because you know both its origin (the vertex) and its direction (this line above).

apply Plane.Raycast like before to get the actual projection.

(**important edit:** in fact, I was wrong here – you cannot use the same imaginary plane as before because at least half of the points are on the wrong side of it; **easy fix:** make another plane that is the same thing as the previous one, but this one contains camera.transform.position instead of cube.transform.position; this will simply migrate this new plane to go through the camera instead, but is oriented the same; this way you’re sure that all of the vertices lie in front of it, so no problems. **important edit 2:** sorry, nope this will invalidate the projection due to the fact that all vertex rays converge toward the camera position. you need to push the plane a little bit forward from the camera, and basically here is the distance you can use: camera.nearClipPlane; this is not a plane as suggested by the name, but merely a configurable distance, thus `new Plane(-camera.transform.forward, camera.transform.position + camera.nearClipPlane * camera.transform.forward);`

; this should work more or less, but there might be problems with accuracy)

now you can create a Bounds object with your ~~cube’s center~~ **edit:** camera’s position as the first point, and set its size to `Vector3.zero`

. you then use Encapsulate to add each projection point and this will grow the bounds automatically.

keep in mind that Bounds is a 3D bounding box representation, so if your plane is angled in world space, the bounding box will be invalid, because it is always axis-aligned.

if you know that your plane is always axis-aligned as well, then ignore this step, but if not, you can temporarily rotate your points to fall exactly onto the XY plane, for this step to work properly.

to do this you need to find the world space rotation of your plane, and rotate the points mathematically **before** you add them to Bounds.

for convenience, we’ll pick the XY plane as our target plane, so the coordinates should all turn out as (x, y, n) where n will be the same for all projection points, and thus you can ignore it. this will effectively give you world-space independent 2D coordinates, from which you can easily obtain the screen-projected width/height of the cube.

remember your plane normal vector? this is the direction in which your plane is oriented in the world space. you can access it through plane.normal

the XY plane’s normal is simply Vector3.back, it’s a direction that points to you directly from the screen. to obtain the rotation from plane.normal to Vector3.back, you simply do

```
var rotation = Quaternion.FromToRotation(plane.normal, Vector3.back);
```

now you simply multiply this with a projection point, and that’s it

```
bounds.Encapsulate(rotation * projection[i]);
```

(make sure to treat the ~~cube’s center~~ **edit:** camera position point the same way when you’re instantiating the Bounds object for the first time!)

you should end up with a bounding box that has 3D extents where x will give you half of the cube’s apparent width, y is half of the cube’s apparent height, and z you can completely ignore (in fact, it should be very close to zero).

**finally (3)**, you can use all of this to come up with a basic proportion computation to change camera parameters (mainly you want to move it in the direction of -plane.normal, once you know its pointing to cube’s center) in such a way that the 2D extents match up with the frustrum points.

I understand this is too much text, but the actual code is really simple and without too many lines or some heavy math, so if you try to digest this step by step, it shouldn’t be too hard for anyone really. if I’ll have some spare time, I might do it, but in the meantime, try it on your own. no promises though.