How do I add a MeshCollider to my randomly generated island through Code

Hi, so im working on a procedural generated isand (like in the game “Muck” from Dani) but i am struggeling with adding colliders to the mesh through code. It would be great if someone could help me with that. The Code is from this Video:

He also made a tutorial about including colliders, but he is implementing it in a script for procedural generation and i dont really need that. Anyway, here is my code where i would like to include the mesh collider script:

using UnityEngine;
using System.Collections;
public static class MeshGenerator 
{
    
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, 
    AnimationCurve heightCurve, int levelOfDetail)
    {
        int width = heightMap.GetLength (0);
        int height = heightMap.GetLength (1);
        float topLeftX = (width -1) / -2f;
        float topLeftZ = (height -1) / 2f;
        int meshSimplificationIncrement = (levelOfDetail ==0)?1:levelOfDetail * 2;
        int verticesPerLine = (width-1)/meshSimplificationIncrement + 1;
        MeshData meshData = new MeshData(verticesPerLine, verticesPerLine);
        int vertexIndex = 0;
        for(int y = 0; y <height; y+= meshSimplificationIncrement)
        {
            for(int x = 0; x < width; x+= meshSimplificationIncrement)
            {
                meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate( 
                heightMap[x,y]) * heightMultiplier, topLeftZ - y);
                meshData.uvs[vertexIndex] = new Vector2(x/(float)width,y/(float)height);
                if(x < width -1 && y < height -1)
                {
                    meshData.AddTriangle(vertexIndex, vertexIndex+ verticesPerLine + 1, vertexIndex + 
                    verticesPerLine);
                    meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1);
                }
                
                vertexIndex++;
            }
        }
        return meshData;
    }
}
public class MeshData
{
    public Vector3[] vertices;
    public int[] triangles;
    public Vector2[] uvs;
    int triangleIndex;
    public MeshData(int meshWidth, int meshHeight)
    {
        vertices = new Vector3[meshWidth * meshHeight];
        uvs = new Vector2[meshWidth * meshHeight];
        triangles = new int[(meshWidth-1)*(meshHeight-1)*6];
    }
    public void AddTriangle(int a, int b, int c)
    {
        triangles [triangleIndex] = a;
        triangles [triangleIndex+1] = b;
        triangles [triangleIndex+2] = c;
        triangleIndex += 3;
    }
    public Mesh CreateMesh()
    {
        
        Mesh mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.uv = uvs;
        mesh.RecalculateNormals();
        return mesh;
    }
}

It could be possible that the collider has to be included in one of the other scripts, but i think that should be the right one.
If you can help me with this, thank you very much in advance!

3 Answers

3

How do I add a MeshCollider?
Idk, easily?
_
MeshGeneratorTester.cs

using UnityEngine;

[RequireComponent( typeof(MeshFilter) )]
[RequireComponent( typeof(MeshRenderer) )]
[RequireComponent( typeof(MeshCollider) )]
class MeshGeneratorTester : MonoBehaviour
{
    [SerializeField] int _width = 101;
    [SerializeField] int _height = 101;
    [SerializeField] AnimationCurve _heightCurve = new AnimationCurve( new Keyframe(0,0) , new Keyframe(1,1) );
    Mesh _mesh;
    #if UNITY_EDITOR
    void OnValidate ()
    {
        if( _mesh!=null )
        {
            if( Application.isPlaying ) Object.Destroy( _mesh );
            else Object.DestroyImmediate( _mesh );
        }
        float[,] heightmap = new float[_width,_height];
        for( int y=0 ; y<_height ; y++ )
        for( int x=0 ; x<_width ; x++ )
        {
            heightmap[x,y] = Random.Range( 0 , 1f );
        }
        var meshdata = MeshGenerator.GenerateTerrainMesh( heightmap , 10f , _heightCurve , 1 );
        _mesh = meshdata.CreateMesh();
        GetComponent<MeshFilter>().sharedMesh = _mesh;
        GetComponent<MeshCollider>().sharedMesh = _mesh;
    }
    #endif
}
public static class MeshGenerator
{
    public static MeshData GenerateTerrainMesh (
        float[,] heightMap ,
        float heightMultiplier ,
        AnimationCurve heightCurve ,
        int levelOfDetail
    )
    {
        int width = heightMap.GetLength(0);
        int height = heightMap.GetLength(1);
        float topLeftX = (width -1) / -2f;
        float topLeftZ = (height -1) / 2f;
        int meshSimplificationIncrement = (levelOfDetail ==0)?1:levelOfDetail * 2;
        int verticesPerLine = (width-1) / meshSimplificationIncrement + 1;
        MeshData meshData = new MeshData( verticesPerLine , verticesPerLine );
        int vertexIndex = 0;
        for( int y=0 ; y<height ; y+=meshSimplificationIncrement )
        for( int x=0 ; x<width ; x+=meshSimplificationIncrement )
        {
            meshData.vertices[vertexIndex] = new Vector3(
                topLeftX + x ,
                heightCurve.Evaluate( heightMap[x,y]) * heightMultiplier ,
                topLeftZ - y
            );
            meshData.uvs[vertexIndex] = new Vector2(
                x / (float)width ,
                y / (float)height
            );
            if( x<width-1 && y<height-1 )
            {
                meshData.AddTriangle( vertexIndex , vertexIndex+verticesPerLine+1 , vertexIndex+verticesPerLine );
                meshData.AddTriangle( vertexIndex+verticesPerLine+1 , vertexIndex , vertexIndex+1 );
            }
            
            vertexIndex++;
        }
        return meshData;
    }
}

public class MeshData
{
    public Vector3[] vertices;
    public int[] triangles;
    public Vector2[] uvs;
    int triangleIndex;
    public MeshData(int meshWidth, int meshHeight)
    {
        vertices = new Vector3[meshWidth * meshHeight];
        uvs = new Vector2[meshWidth * meshHeight];
        triangles = new int[(meshWidth-1)*(meshHeight-1)*6];
    }
    public void AddTriangle(int a, int b, int c)
    {
        triangles [triangleIndex] = a;
        triangles [triangleIndex+1] = b;
        triangles [triangleIndex+2] = c;
        triangleIndex += 3;
    }
    public Mesh CreateMesh()
    {
        Mesh mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.uv = uvs;
        mesh.RecalculateNormals();
        return mesh;
    }
}

I finally did it!! Its a bit painfull to see how easy it actually was, but im very glad i figured it out.
The only thing i did was to add this small script to my Mesh object:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

    public class AddCollider : MonoBehaviour
    {
        GameObject mesh;
    
        void Awake()
        {
            mesh = GameObject.Find ("Mesh");
            mesh.AddComponent<MeshCollider>();
        }
    
    }

@andrew-lukasik thanks for your answers, you gave me the idea to put the script directly on the Mesh!
Man, I really do love programming :DD

hello I thank you so much I was trying to find the same code but do you have a code that when I change the seed or size it deletes the old terrain collider because It keeps the old collider @Constantin_de