More questions on generating camera frustrum

According to the documentation this function should return the six planes that make up the camera fustrum. (http://unity3d.com/support/documentation/ScriptReference/GeometryUtility.CalculateFrustumPlanes.html)

GeometryUtility.CalculateFrustumPlanes();

and also according to the documentation, the following code should turn those 6 planes into mesh planes in order to create geometry that makes up the camera frustrum

public class example : MonoBehaviour {
private Camera cam;
private Plane[] planes;
void Start() {
    cam = Camera.main;
    planes = GeometryUtility.CalculateFrustumPlanes(cam);
    int i = 0;
    while (i < planes.Length) {
        GameObject p = GameObject.CreatePrimitive(PrimitiveType.Plane);
        p.name = "Plane " + i.ToString();
        p.transform.position = -planes_.normal * planes*.distance;*_

p.transform.rotation = Quaternion.FromToRotation(Vector3.up, planes*.normal);*
i++;
}
}
}
However when I try to run this code, I just get random planes floating in random places in my world. Anyone have any idea why? My goal is to create a textured transparent box that represents the frustum of a security camera.

No, it won’t work that way. The planes you get back from CalculateFrustumPlanes are logical infinite planes. They don’t have a limit. The example code just creates 6 square meshes that are placed on the logical planes. I’ve tested the code and all planes are correct. All planes faces their normal direction. The position is quite irrelevant since the planes are infinite.

If you want to create a Mesh that represents the viewing frustum, the 4 sides are not squares, they are trapezoids. You could get the corners of this volume by intersecting 3 planes but that’s kinda complicated. It’s much easier to use [Camera.ViewportToWorldPoint][1].

edit

I’ve created a “small” extention for the Camera class so you can create a frustumMesh with a single function.

public static class CameraExtention
{
    private static int[] m_VertOrder = new int[24]
    {
        0,1,2,3, // near
        6,5,4,7, // far
        0,4,5,1, // left
        3,2,6,7, // right
        1,5,6,2, // top
        0,3,7,4  // bottom
    };
    private static int[] m_Indices = new int[36]
    {
         0,  1,  2,  3,  0,  2, // near
         4,  5,  6,  7,  4,  6, // far
         8,  9, 10, 11,  8, 10, // left
        12, 13, 14, 15, 12, 14, // right
        16, 17, 18, 19, 16, 18, // top
        20, 21, 22, 23, 20, 22, // bottom
    }; //              |______|---> shared vertices

    public static Mesh GenerateFrustumMesh(this Camera cam)
    {
        Mesh mesh = new Mesh();
        Vector3[] v = new Vector3[8];
        v[0] = v[4] = new Vector3(0,0,0);
        v[1] = v[5] = new Vector3(0,1,0);
        v[2] = v[6] = new Vector3(1,1,0);
        v[3] = v[7] = new Vector3(1,0,0);
        v[0].z = v[1].z = v[2].z = v[3].z = cam.nearClipPlane;
        v[4].z = v[5].z = v[6].z = v[7].z = cam.farClipPlane;
        // Transform viewport --> world --> local
        for (int i = 0; i < 8; i++)
            v _= cam.transform.InverseTransformPoint(cam.ViewportToWorldPoint(v*));*_

Vector3[] vertices = new Vector3[24];
Vector3[] normals = new Vector3[24];
// Split vertices for each face (8 vertices → 24 vertices)
for (int i = 0; i < 24; i++)
vertices = v[m_VertOrder*];
_// Calculate facenormal*
for (int i = 0; i < 6; i++)
{
Vector3 faceNormal = Vector3.Cross(vertices[i*4+2] - vertices[i*4+1],vertices[i*4+0] - vertices[i*4+1]);
normals[i*4+0] = normals[i*4+1] = normals[i*4+2] = normals[i*4+3] = faceNormal;
}
mesh.vertices = vertices;
mesh.normals = normals;
mesh.triangles = m_Indices;
return mesh;
}
}
With that class somewhere in your project you can simply do that:
camera.GetComponent().mesh = camera.GenerateFrustumMesh();
*[1]: http://unity3d.com/support/documentation/ScriptReference/Camera.ViewportToWorldPoint.html*_