Here you say you have a cube, and yet in that other thread you claimed you don’t have a cube, that it’s just an simplified illustration for a more general problem.
Look, the general idea behind this is what I already answered there, however if you are working with a cube, the solution is incredibly simple and boils down to finding dots with cube surface normals.
This sentence contains a horrible problem as well. “Relative angle of the cube” is not the same as “amount of each face visible”. The latter can be a very hard problem because it involves knowing the absolute render area which depends on the distance from the object, camera’s field of view, and most importantly the skewness of camera’s direction against the center of the object. That said, if the object is known to be a cube, you can somewhat approximate the areas if you know the surface normals’ angles.
Again, as I explained in the other thread, you can compute the relative angle of the cube if you obtain the difference between two orientations, where one is the orientation (world-space rotation) of the cube, and the other corresponds to the orientation of the camera as if the target object was in the origin.
With this difference (represented with a quaternion) you can use the Unity’s API to obtain per-axis Euler angles from it.
If you need this angle to be expressed on a single plane (say XZ), all you need to do is to project the camera’s direction onto this plane, which is as easy as
Vector3 projectDirectionToXZ(Vector3 dir) => new(dir.x, 0f, dir.z).normalized;
Unfortunately, I really really don’t have time right now to make you a useful prototype, but rest assured that this solution is very easy to implement and modify.
Once more, if you do have a cube, you can obtain the cube’s front surface normal simply by taking cube.transform.forward, and then you dot this against camera.transform.forward, and if the result is close to -1 the two are looking at each other (aka lie anti-parallel; this is because a\cdot b=\|a\|\|b\| \cos(\theta) and because directions are unit vectors {\cos(180^\circ)=-1}). You can very easily detect the most dominant face (of a cube) by doing this
static Vector3[] _n;
Vector3 getDominantNormal(Vector3 lookDir) {
_n??= new Vector3[6] {
Vector3.right, Vector3.up, Vector3.forward,
-Vector3.right, -Vector3.up, -Vector3.forward
};
var smallest = float.PositiveInfinity;
int index = -1;
for(int i = 0; i < _n.Length; i++) {
var d = Vector3.Dot(_n[i], lookDir);
if(smallest > d) {
smallest = d;
index = i;
}
}
return _n[index];
}
It’s a sloppy example, could be much more streamlined, but should get the work done.
Similarly you can get all faces that are visible by camera
static Vector3[] _n;
int getListOfVisibleFaces(List<Vector3> results, Vector3 lookDir) {
_n??= new Vector3[6] {
Vector3.right, Vector3.up, Vector3.forward,
-Vector3.right, -Vector3.up, -Vector3.forward
};
results.Clear();
for(int i = 0; i < _n.Length; i++) {
var d = Vector3.Dot(_n[i], lookDir);
if(d < 0f) results.Add(_n[i]);
}
return results.Count;
}
make sure to instantiate the results list before calling, i.e.
var list = new List<Vector3>();
if(getListOfVisibleFaces(list, camera.transform.forward) > 0) {
// do something with list elements
}
If you also have a cube that is rotating freely, then do this
static Vector3[] _n;
int getListOfVisibleFaces(List<Vector3> results, Vector3 lookDir, Quaternion? cubeRotation = null) {
_n??= new Vector3[6] {
Vector3.right, Vector3.up, Vector3.forward,
-Vector3.right, -Vector3.up, -Vector3.forward
};
results.Clear();
var rot = cubeRotation.HasValue? cubeRotation.Value : Quaternion.identity;
for(int i = 0; i < _n.Length; i++) {
var d = Vector3.Dot(rot * _n[i], lookDir);
if(d < 0f) results.Add(_n[i]);
}
return results.Count;
}
var list = new List<Vector3>();
if(getListOfVisibleFaces(list, camera.transform.forward, cube.transform.rotation) > 0) {
// do something with list elements
}
Edit:
fixed typo in the first example