3

I've been working on building a procedural generator for Unity, that takes in noise and uses it to build a height map.

So far, everything seems to work as long as I limit the size of the mesh to around 250x250. If I attempt to make a larger mesh, the script won't calculate it.

The puzzling thing is that I get no memory errors or anything of that nature. I've implemented a Regenerate button that allows me to generate a new mesh in Unity and as long as I remain in the range of 250x250 or less, it works fine. If I pick a larger value, the mesh simply remains unchanged.

How I calculate the Mesh:

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;

[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(Noise))]
public class CustomTerrain : MonoBehaviour {
    //Note: sizeX*sizeZ determines mesh size.
    public int sizeX = 4; //These values are public so they can be
    public int sizeZ = 4; //modified in the Unity Editor.
    public float noiseSize = 1.0f; 
    public float cellSize = 1.0f;
    private string mPath = "Assets/Generated/";
    Noise noise;

    void Start() {
        noise = GetComponent<Noise>();
        this.LoadMesh();
        if (!GetComponent<MeshFilter>().sharedMesh) {
            this.Regenerate();
        }
    }
    public void LoadMesh() {
        Mesh mesh = Instantiate(AssetDatabase.LoadMainAssetAtPath(mPath + gameObject.name + ".asset") as Mesh);
        if (mesh) {
            GetComponent<MeshFilter>().mesh = mesh;
        }
        recalculateMeshCollider(mesh);
    }

    Vector3[] GenVertices() {
        float x, z;
        int w = (sizeX+1);
        int l = (sizeZ+1);
        Vector3[] vertices = new Vector3[w*l];
        for (int gx = 0; gx < w; gx++) {
            for (int gz = 0; gz < l; gz++) {
                x = gx*cellSize;
                z = gz*cellSize;
                float height = (noiseSize * noise.Get(x,z));
                vertices[gx*l+gz] = new Vector3(x, height, z);
            }
        }
        return vertices;
    }

    int[] GenTriangles() {
        int vertciesPerTriangle = 3;
        int trianglesPerCell = 2;
        int numberCells = sizeX * sizeZ;
        int[] triangles = new int[vertciesPerTriangle * trianglesPerCell * numberCells];

        int tIndeX = 0;
        for (int cX = 0; cX < sizeX; cX++) {
            for (int cZ = 0; cZ < sizeZ; cZ++) {
                int n = cX*(sizeZ+1)+cZ;

                triangles[tIndeX] = n;
                triangles[tIndeX+1] = n+1;
                triangles[tIndeX+2] = n+sizeZ+2;
                triangles[tIndeX+3] = n;
                triangles[tIndeX+4] = n+sizeZ+2;
                triangles[tIndeX+5] = n+sizeZ+1;
                tIndeX +=6;
            }
        }
        return triangles;
    }

    Vector2[] GenUVs() {
        int w = (sizeX + 1);
        int l = (sizeZ + 1);
        Vector2[] uvs = new Vector2[w * l];

        for (int uX = 0; uX < w; uX++) {
            for (int uZ = 0; uZ < l; uZ++) {
                uvs[uX*l+uZ] = new Vector2((float)uX/sizeX, (float)uZ/sizeZ);
            }
        }
        return uvs;
    }
}

My Regenerate function:

public void Regenerate() {
    noise.Init();
    Mesh mesh = GetComponent<MeshFilter>().sharedMesh;
    if(!mesh) {
        mesh = new Mesh();
        GetComponent<MeshFilter>().sharedMesh = mesh;
    }
    mesh.vertices = GenVertices();
    mesh.triangles = GenTriangles();
    mesh.uv = GenUVs();
    mesh.RecalculateNormals();
    recalculateMeshCollider(mesh);
}

public void recalculateMeshCollider(Mesh mesh) {
    if (GetComponent<MeshCollider>()) {
        DestroyImmediate(GetComponent<MeshCollider>());
    }
    transform.gameObject.AddComponent<MeshCollider>();
    transform.GetComponent<MeshCollider>().sharedMesh = mesh;
}
  • Just BTW, many engineers who come to Unity start cutting up mesh, and then begin writing a beautiful occlusion ... only to then realize, Unity actually has fantastic culling built-in!! it's all automatic, use your judgement to choose a good chunk size. – Fattie Feb 04 '16 at 20:25

1 Answers1

4

By "250x250" do you mean there's 62.400 triangles?

Unity has a vertex limit of 65535 count - just use more than one mesh, no trouble.

Fattie
  • 27,874
  • 70
  • 431
  • 719
  • 1
    That would certainly explain why I can't make larger meshes. I was worried that there was a fault in my code, hence why I asked. Thank you for informing me of this. – Einar Örn Gissurarson Feb 04 '16 at 20:13
  • Right, sorry to be "of no help!" :) Yes it's a nuisance hitting that limit. By the way for any new Unity explorers googling to here, some general chat on mesh in Unity http://answers.unity3d.com/questions/263302/vertices-array-in-mesh-vertices.html http://answers.unity3d.com/questions/423569/meshvertices-is-too-small.html http://answers.unity3d.com/questions/266972/detecting-mesh-orientation.html !!! – Fattie Feb 04 '16 at 20:21
  • Also for any new readers, watch out for the classic Gotchya in Unity, when you write .vertices it **makes a copy** for goodness sake. See many posts on this http://answers.unity3d.com/answers/417487/view.html !!! – Fattie Feb 04 '16 at 20:23