I am procedurally generating a large terrain as a group of overlapping power-of-two sized meshes, where the meshes are all attached to individual GameObjects which in turn are all children of a single GameObject. This works fine in my project. I saved the parent GameObject as a prefab. When I load it with:

bathyhead = Instantiate(Resources.Load(“FullGridBoss”)) as GameObject;

the bathyhead GameObject is generated, along with all its children, but, the Mesh Filter and Mesh Collider mesh return as “None (Mesh)” in their respective boxes in the inspector. So, of course, the terrain is not visible, unless I generate it with each play.

Since everything else appears to make it back from the prefab in the inspector, including the Mesh Renderer material, I’m wondering why the collider and filter meshes don’t?

Here is the code that generates the meshes:

```
Bathy = new GameObject[x_meshes,z_meshes];
for (int i=0; i<x_meshes; i++) {
for (int j=0; j<z_meshes; j++){
// Generate named gameobjects and make them children of bathyBoss object.
// It isn't strictly necessary to provide names for the GameObjects
// generated by the script, but, they show up in the hierarcy at run
// time so they look cleaner, and being able to find by name helps in
// clean up for regenerations and such.
string goname = System.String.Format("Bathy_{0}{1}",i,j);
Bathy[i,j] = new GameObject(goname);
Bathy[i,j].transform.parent = bathyBoss.transform;
Bathy[i,j].AddComponent<MeshRenderer>();
Bathy[i,j].AddComponent<MeshFilter>();
//Bathy[i,j].AddComponent<ShowMeshVertices>();
Material bathmat = Resources.Load("Materials/BathyMaterial",typeof(Material)) as Material;
if(bathmat != null) {
MeshRenderer mr = Bathy[i,j].GetComponent<MeshRenderer>(); // already has albedo image, and
mr.material = bathmat; // UVs pull out the proper segment
} else { // so this works for all meshes
Debug.Log("couldn't find bathmat"); // maybe update albedo image in
} // script someday so can change
// region
Mesh bathy = new Mesh();
bathy.vertices = GenVertices(i,j);
Bathy[i,j].GetComponent<MeshFilter>().sharedMesh = bathy;
// make sure the gameobject is at the same location (centered) on each mesh
Bounds bathybounds = Bathy[i,j].GetComponent<MeshFilter>().sharedMesh.bounds;
Vector3 gopos = new Vector3(0f,0f,0f);
Vector3 offset = Bathy[i,j].transform.position - Bathy[i,j].transform.TransformPoint(bathybounds.center);
Bathy[i,j].transform.position = gopos + offset;
// position mesh's gameobject for correct overlap
/*
ij
10 | 11
---+---
00 | 01
*/
float x_off = (float)i*x_cells*x_cell_size;
float z_off = (float)j*z_cells*z_cell_size;
Bathy[i,j].transform.position = new Vector3(x_off,0f,z_off);
bathy.triangles = GenTriangles ();
bathy.uv = GenUVs (i,j);
bathy.RecalculateNormals ();
// add a mesh collider for flythrough terrain avoidance
MeshCollider mshcol = Bathy[i,j].AddComponent(typeof(MeshCollider)) as MeshCollider;
mshcol.sharedMesh = bathy;
}
}
}
Vector3[] GenVertices(int mx, int mz) { // generate vertices for mesh mx,mz
//Debug.Log ("gen " + mx + " " + mz);
int w = x_cells + 1;
int l = z_cells + 1;
Vector3[] vertices = new Vector3[w*l];
for (int x=0; x<w; x++) {
for (int z=0; z<l; z++) {
// calculate full grid x,y from current mesh x,y to map to Get_Y() vertice pool
int gx = x + mx * x_cells;
int gz = z + mz * z_cells;
float ve = x_cell_size*VertExag/1000f; // compensate for (square) cell size world units (smaller means less)
float height = grid.Get_Y(gx,gz,ve);
vertices[x*l+z] = new Vector3(x*x_cell_size,height,z*z_cell_size);
}
}
return vertices;
}
// linear array of indices that point into the vertex array - same for all multiple meshes
int[] GenTriangles(){
int verts_per_tri = 3;
int tris_per_cell = 2;
int num_cells = x_cells*z_cells;
int[] triangles = new int[num_cells*tris_per_cell*verts_per_tri];
int tindex=0;
for (int cx=0; cx<x_cells; cx++) {
for (int cz=0; cz<z_cells; cz++) {
int n = cx*(z_cells+1)+cz;
triangles[tindex] = n;
triangles[tindex+1] = n+1;
triangles[tindex+2] = n+z_cells+2;
tindex+=3;
triangles[tindex] = n;
triangles[tindex+1] = n+z_cells+2;
triangles[tindex+2] = n+z_cells+1;
tindex+=3;
}
}
return triangles;
}
// UVs are mapping of each point on the 3D surface to a vertex in the mesh - segmented for each mesh
Vector2[] GenUVs(int mx,int mz) {
int w = x_cells + 1;
int l = z_cells + 1;
Vector2[] uvs = new Vector2[w*l];
float minx = (float)mx/x_meshes; // current segment UV value ranges
float maxx = ((float)mx + 1.0f)/x_meshes; // +1 since mesh count, not cell count
float xdif = maxx-minx;
float minz = (float)mz/z_meshes;
float maxz = ((float)mz + 1.0f)/z_meshes;
float zdif = maxz-minz;
for (int ux=0; ux<w; ux++) {
for (int uz=0; uz<l; uz++) {
uvs[ux*l+uz] = new Vector2(minx + xdif*(float)ux/x_cells,
minz + zdif*(float)uz/z_cells);
}
}
return uvs;
}
```