Mesh generated at run-time gets frustum-culled too early

I have a mesh generation function that gets called at runtime OR in the editor:

void GenerateAtRunTime() {
    if (!generated && someCriterion) {
        GetComponent<MeshFilter>().sharedMesh = Generator.Generate(/* arguments */);
        generated = true;
    }
}

[ContextMenu("Pre-generate")]
void PreGenerate() {
    if (!generated) {
        GetComponent<MeshFilter>().sharedMesh = Generator.Generate(/* arguments */);
        generated = true;
    }
}

if I call it from the editor, all is fine. If I don't the mesh is culled too early: as soon as the center of bounds is out of view, as if it's bounds had size of 0.

The Generator.Generate is like:

    Mesh mesh = new Mesh();
    Vector3[] v = new Vector3[vtxCount];
    Vector2[] uv = new Vector2[vtxCount];
    Color[] c = new Color[vtxCount];
    int[] tri = new int[triCount];

    // .... actually generate here .....

    mesh.vertices = v;
    mesh.colors = c;
    mesh.uv = uv;
    mesh.triangles = tri;
    mesh.RecalculateBounds();

    return mesh;

(I know that assigning triangles recalculates bounds, I'm just that desperate)

as a debugging help I set up the following:

[ContextMenu("Print me")]
void PrintMe()
{
    Debug.Log(string.Format("{0} renderer bounds: {1}", 
        gameObject.name, GetComponent<MeshRenderer>().bounds));
    Debug.Log(string.Format("{0} mesh bounds: {1}", 
        gameObject.name, GetComponent<MeshFilter>().sharedMesh.bounds));
}

void OnDrawGizmos()
{
    Gizmos.DrawWireCube(renderer.bounds.center, renderer.bounds.size);
}

...and bounds seem fine and identical in either case. What am I missing when generating meshes on the fly?

I had the exact same problem. And my setup didn’t allow me to use your solution.

I knew you were on the right track with the mesh bounds not being handled properly. Since collision with the same mesh worked fine, I reasoned that the MeshRenderer or MeshFilter was the one who needed to be poked.

So I tried playing around with the notifications and it turned out that, this failed:

renderInfo.mesh.RecalculateBounds();
renderInfo.gameObject.GetComponent<MeshFilter>().mesh = renderInfo.mesh;

And this succeeded:

renderInfo.gameObject.GetComponent<MeshFilter>().mesh = renderInfo.mesh;
renderInfo.mesh.RecalculateBounds();

So this is clearly a bug, either RecalculateBounds doesn’t work when the mesh isn’t attached to a transform, or setting the mesh property of the MeshFilter doesn’t update/notify properly.

I'm not sure why (and I would like to hear the explanation) but the following has solved the problem: the generator now doesn't create a new mesh but modifies a mesh passed as an argument. Script that triggers the generation has become:

void GenerateAtRunTime() {
    if (!generated && someCriterion) {
        Generator.Generate(GetComponent<MeshFilter>().mesh, /* other arguments */);
        generated = true;
    }
}

(if I understand correctly, accessing `mesh` property creates a mesh when there wasn't one, but apparently it actually does something else to it behind the scene).

Use RecalculateBounds() after you assign the mesh to a MeshFilter component. So for example in C#:

GetComponent().mesh = aMeshObject;
aMeshObject.RecalculateBounds();

This way it will recalculate renderer bounds.

Had a similar issue, posted an answer on this thread:

See http://answers.unity3d.com/questions/29948/disable-frustum-culling/52479#52479