Smooth Voxel terrain. How is it done?

Hello Unity Community!

I am a young student developer and started off with Unity a few months ago. I understand most of the basics and I started following these tutorials for Voxel terrain engines:

http://forum.unity3d.com/threads/198651-Tutorial-Procedural-meshes-and-voxel-terrain-C

http://www.youtube.com/watch?v=_3ZODVA0yKQ

I’m planning on making a smooth, destructible Voxel terrain, like in these games:

Yogventures

Castle Story

Windbourne

TUG

I’ve read a few Threads: (After playing Minecraft… etc). I read that one solution would be making a basic Voxel terrain and changing the mesh’s vertices depending on its neighbours. I tried this on a 2D terrain. Here’s the code:

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

public class SmoothPolygonGeneratorTest : MonoBehaviour {
	
	public List<Vector3> newVertices = new List<Vector3>();
	public List<int> newTriangles = new List<int>();
	public List<Vector2> newUV = new List<Vector2>();
	
	public List<Vector3> colVertices = new List<Vector3>();
	public List<int> colTriangles = new List<int>();
	private int colCount;
	
	private Mesh mesh;
	private MeshCollider col;
	
	private float tUnit = 0.25f;
	private Vector2 tStone = new Vector2 (1, 0);
	private Vector2 tGrass = new Vector2 (0, 1);
	private Vector2 tRandom = new Vector2 (0, 2);
	
	public byte[,] blocks;
	private int squareCount;
	public bool update=false;
	
	
	// Use this for initialization
	void Start () {
		mesh = GetComponent<MeshFilter> ().mesh;
		col = GetComponent<MeshCollider> ();
		
		GenTerrain();
		BuildMesh();
		UpdateMesh();
	}
	
	void Update(){
		if(update){
			BuildMesh();
			UpdateMesh();
			update=false;
		}	
	}
	
	
	int NoiseInt (int x, int y, float scale, float mag, float exp){
		
		return (int) (Mathf.Pow ((Mathf.PerlinNoise(x/scale,y/scale)*mag),(exp) ));
		
		
	}
	
	void GenTerrain(){
		blocks=new byte[96,128];
		
		for(int px=0;px<blocks.GetLength(0);px++){
			int stone= NoiseInt(px,0, 80,15,1);
			stone+= NoiseInt(px,0, 50,30,1);
			stone+= NoiseInt(px,0, 10,10,1);
			stone+=75;
			
			
			int dirt = NoiseInt(px,0, 100f,35,1);
			dirt+= NoiseInt(px,100, 50,30,1);
			dirt+=75;
			
			
			for(int py=0;py<blocks.GetLength(1);py++){
				if(py<stone){
					blocks[px, py]=1;
					
					if(NoiseInt(px,py,12,16,1)>10){  //dirt spots
						blocks[px,py]=2;
						
					}
					
					if(NoiseInt(px,py*2,16,14,1)>10){ //Caves
						blocks[px,py]=0;
						
					}
					
				} else if(py<dirt) {
					blocks[px,py]=2;
				}
				
				
			}
		}
	}
	
	void BuildMesh(){
		for(int px=1;px<blocks.GetLength(0);px++){
			for(int py=1;py<blocks.GetLength(1);py++){
				
				if(blocks[px,py]!=0){
					
					if(blocks[px,py]==1){
						if(Block(px, py + 1)==0 && Block(px, py-1) == 0) {
							if(Block (px + 1, py) != 0 && Block (px - 1, py)== 0) {
								SmoothTerrain(px,py,7,tStone,0f);
							}
							else if (Block (px + 1, py) == 0 && Block (px -1, py) != 0) {
								SmoothTerrain(px,py,8,tStone,0f);
							}
							else if(Block(px - 1, py)==0 || Block(px + 1, py)==0) {
								SmoothSquare(px,py,tStone,0f,0f);
							}
							else if (Block(px - 1, py)!=0 || Block(px + 1, py)!=0) {
								SmoothSquare(px,py,tStone,0f,0f);
							}
						}
						else if(Block(px, py + 1 )==0 && Block(px,py -1)!=0) {
							if(Block(px + 1, py)!=0 && Block(px- 1, py)==0) {
								if (CheckBlock(px + 2,py) != 0 && CheckBlock(px + 1, py +1) == 0){
									SmoothTerrain(px,py,1,tStone,0.4f);
								}
									else {
									SmoothTerrain(px,py,1,tStone,0f);
								}
							}
							else if(Block(px - 1, py)!=0 && Block(px + 1, py)==0){
								if (CheckBlock(px - 2,py) != 0 && CheckBlock(px - 1, py +1) == 0){
									SmoothTerrain(px,py,2,tStone,0.4f);
								}
								else {
									SmoothTerrain(px,py,2,tStone,0f);
								}
								}
							else if(Block(px - 1, py)==0 || Block(px + 1, py)==0) {
								SmoothTerrain(px,py,3,tStone, 0f);
							}
							else if (Block(px - 1, py)!=0 || Block(px + 1, py)!=0) {
								if(CheckBlock(px-2,py) ==0 && CheckBlock(px-1, py +1)==0) {
									SmoothSquare(px,py,tStone,0.4f,0f);
								}
								else if(CheckBlock(px+2,py) ==0 && CheckBlock(px+1, py +1)==0) {
									SmoothSquare(px,py,tStone,0f,0.4f);
								}
								else {
									SmoothSquare(px,py,tStone,0f,0f);
								}
							}
							}
						else if(Block(px, py -1)==0 && Block (px, py +1)!=0) {
							if(Block(px + 1, py)!=0 && Block(px- 1, py)==0) {
								SmoothTerrain(px,py,4,tStone, 0f);
							}
							else if(Block(px - 1, py)!=0 && Block(px + 1, py)==0){
								SmoothTerrain(px,py,5,tStone, 0f);
							}
							else if(Block(px - 1, py)==0 || Block(px + 1, py)==0) {
								SmoothTerrain(px,py,6,tStone, 0f);
							}
							else if (Block(px - 1, py)!=0 || Block(px + 1, py)!=0) {
								SmoothSquare(px,py,tStone,0f,0f);
							}
						
						}
						else if(Block (px, py -1) != 0 && Block (px, py + 1) != 0) {
							if(Block (px + 1, py) == 0 && Block (px -1, py) == 0){
								SmoothSquare(px,py,tStone,0f,0f);
							}
							else if (Block (px + 1, py) != 0 && Block (px - 1, py) == 0) {
								SmoothSquare(px,py,tStone,0f,0f);
							}
							else if (Block (px + 1, py) == 0 && Block (px - 1, py) != 0) {
								SmoothSquare(px,py,tStone,0f,0f);
							}
							else if(Block (px + 1, py)!= 0 && Block (px- 1, py)!= 0){ 
								GenSquare(px,py,tStone);
							}
						}

					
					} else if(blocks[px,py]==2){
						if(Block(px, py + 1)==0 && Block(px, py-1) == 0) {
							if(Block (px + 1, py) != 0 && Block (px - 1, py)== 0) {
								SmoothTerrain(px,py,7,tGrass,0f);
							}
							else if (Block (px + 1, py) == 0 && Block (px -1, py) != 0) {
								SmoothTerrain(px,py,8,tGrass,0f);
							}
							else if(Block(px - 1, py)==0 || Block(px + 1, py)==0) {
								SmoothSquare(px,py,tGrass,0f,0f);
							}
							else if (Block(px - 1, py)!=0 || Block(px + 1, py)!=0) {
								SmoothSquare(px,py,tGrass,0f,0f);
							}
						}
						else if(Block(px, py + 1 )==0 && Block(px,py -1)!=0) {
							if(Block(px + 1, py)!=0 && Block(px- 1, py)==0) {
								if (CheckBlock(px + 2,py) != 0 && CheckBlock(px + 1, py +1) == 0){
									SmoothTerrain(px,py,1,tGrass,0.4f);
								}
								else {
									SmoothTerrain(px,py,1,tGrass,0f);
								}
							}
							else if(Block(px - 1, py)!=0 && Block(px + 1, py)==0){
								if (CheckBlock(px - 2,py) != 0 && CheckBlock(px - 1, py +1) == 0){
									SmoothTerrain(px,py,2,tGrass,0.4f);
								}
								else {
									SmoothTerrain(px,py,2,tGrass,0f);
								}
							}
							else if(Block(px - 1, py)==0 || Block(px + 1, py)==0) {
								SmoothTerrain(px,py,3,tGrass, 0f);
							}
							else if (Block(px - 1, py)!=0 || Block(px + 1, py)!=0) {
								if(CheckBlock(px-2,py) ==0 && CheckBlock(px-1, py +1)==0) {
									SmoothSquare(px,py,tGrass,0.4f,0f);
								}
								else if(CheckBlock(px+2,py) ==0 && CheckBlock(px+1, py +1)==0) {
									SmoothSquare(px,py,tGrass,0f,0.4f);
								}
								else {
									SmoothSquare(px,py,tGrass,0f,0f);
								}
							}
						}
						else if(Block(px, py -1)==0 && Block (px, py +1)!=0) {
							if(Block(px + 1, py)!=0 && Block(px- 1, py)==0) {
								SmoothTerrain(px,py,4,tGrass, 0f);
							}
							else if(Block(px - 1, py)!=0 && Block(px + 1, py)==0){
								SmoothTerrain(px,py,5,tGrass, 0f);
							}
							else if(Block(px - 1, py)==0 || Block(px + 1, py)==0) {
								SmoothTerrain(px,py,6,tGrass, 0f);
							}
							else if (Block(px - 1, py)!=0 || Block(px + 1, py)!=0) {
								SmoothSquare(px,py,tGrass,0f,0f);
							}
							
						}
						else if(Block (px, py -1) != 0 && Block (px, py + 1) != 0) {
							if(Block (px + 1, py) == 0 && Block (px -1, py) == 0){
								SmoothSquare(px,py,tGrass,0f,0f);
							}
							else if (Block (px + 1, py) != 0 && Block (px - 1, py) == 0) {
								SmoothSquare(px,py,tGrass,0f,0f);
							}
							else if (Block (px + 1, py) == 0 && Block (px - 1, py) != 0) {
								SmoothSquare(px,py,tGrass,0f,0f);
							}
							else if(Block (px + 1, py)!= 0 && Block (px- 1, py)!= 0){ 
								GenSquare(px,py,tGrass);
							}
						}
					}
				}
			}
		}
	}
	
	byte Block (int x, int y){
		
		if(x==-1 || x==blocks.GetLength(0) || y==-1 || y==blocks.GetLength(1)){
			return (byte)1;
		}
		
		return blocks[x,y];
	}

	byte CheckBlock (int x, int y) {
		if( x == -1 || x == -2 || x ==blocks.GetLength(0) + 1 || x ==blocks.GetLength(0) || y == -1 || y == -2  || y == blocks.GetLength(1) + 1 || y == blocks.GetLength(1) ) {
			return (byte) 1;
		}
		return blocks[x,y];
	}

	void GenSquare(int x, int y, Vector2 texture){
		
		newVertices.Add( new Vector3 (x  ,  y  , 0 ));
		newVertices.Add( new Vector3 (x + 1 ,  y  , 0 ));
		newVertices.Add( new Vector3 (x + 1 ,  y-1 , 0 ));
		newVertices.Add( new Vector3 (x  ,  y-1 , 0 ));
		
		newTriangles.Add(squareCount*4);
		newTriangles.Add((squareCount*4)+1);
		newTriangles.Add((squareCount*4)+3);
		newTriangles.Add((squareCount*4)+1);
		newTriangles.Add((squareCount*4)+2);
		newTriangles.Add((squareCount*4)+3);
		
		newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
		newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
		newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
		newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));
		
		squareCount++;
		
	}
	
	void UpdateMesh () {
		mesh.Clear ();
		mesh.vertices = newVertices.ToArray();
		mesh.triangles = newTriangles.ToArray();
		mesh.uv = newUV.ToArray();
		mesh.Optimize ();
		mesh.RecalculateNormals ();
		
		newVertices.Clear();
		newTriangles.Clear();
		newUV.Clear();
		squareCount=0;
		
		Mesh newMesh = new Mesh();
		newMesh.vertices = colVertices.ToArray();
		newMesh.triangles = colTriangles.ToArray();
		col.sharedMesh= newMesh;
		
		colVertices.Clear();
		colTriangles.Clear();
		colCount=0;
	}
	void SmoothTerrain(int x, int y, int count, Vector2 texture, float rate) {
		if(count == 1) {
		newVertices.Add( new Vector3 (x  ,  y  , 0 ));
		newVertices.Add( new Vector3 (x + 1 ,  y- rate  , 0 ));
		newVertices.Add( new Vector3 (x + 1 ,  y-1 , 0 ));
		newVertices.Add( new Vector3 (x  ,  y-1 , 0 ));
		
		newTriangles.Add((squareCount*4)+1);
		newTriangles.Add((squareCount*4)+2);
		newTriangles.Add((squareCount*4)+3);
		
		newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
		newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
		newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
		newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));
	
				

				colVertices.Add( new Vector3 (x  ,  y-1  , 1));
				colVertices.Add( new Vector3 (x + 1 ,  y- rate  , 1));
				colVertices.Add( new Vector3 (x + 1 ,  y- rate , 0 ));
				colVertices.Add( new Vector3 (x  ,  y-1  , 0 ));
				
			ColliderTriangles();
				
				colCount++;


			squareCount++;
		}
		else if(count == 2) {
			newVertices.Add( new Vector3 (x  ,  y  , 0 ));
			newVertices.Add( new Vector3 (x  ,  y- rate   , 0 ));
			newVertices.Add( new Vector3 (x + 1 ,  y-1 , 0 ));
			newVertices.Add( new Vector3 (x  ,  y-1 , 0 ));
			
			newTriangles.Add((squareCount*4)+3);
			newTriangles.Add((squareCount*4)+1);
			newTriangles.Add((squareCount*4)+2);
			
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));

			colVertices.Add( new Vector3 (x  ,  y- rate  , 0));
			colVertices.Add( new Vector3 (x  ,  y- rate  , 1));
			colVertices.Add( new Vector3 (x + 1 ,  y-1 , 1 ));
			colVertices.Add( new Vector3 (x +1 ,  y-1  , 0 ));
			
			ColliderTriangles();
			
			colCount++;
			
			squareCount++;
		}

		else if (count == 3) {
			newVertices.Add( new Vector3 (x  ,  y  , 0 ));
			newVertices.Add( new Vector3 (x+1  ,  y-1   , 0 ));
			newVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 0 ));
			newVertices.Add( new Vector3 (x  ,  y-1 , 0 ));
			
			newTriangles.Add((squareCount*4)+3);
			newTriangles.Add((squareCount*4)+2);
			newTriangles.Add((squareCount*4)+1);
			
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));

			colVertices.Add( new Vector3 (x  ,  y-1  , 0));
			colVertices.Add( new Vector3 (x  ,  y-1  , 1));
			colVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 1 ));
			colVertices.Add( new Vector3 (x+0.5f  ,  y-0.5f  , 0 ));

			ColliderTriangles();
			colCount++;
			colVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 0 ));
			colVertices.Add( new Vector3 (x+0.5f  ,  y-0.5f  , 1 ));
			colVertices.Add( new Vector3 (x+1  ,  y-1  , 1 ));
			colVertices.Add( new Vector3 (x+1 ,  y-1  , 0 ));

			ColliderTriangles();
			colCount++;
			squareCount++;

		}
		else if(count == 4) {
			newVertices.Add( new Vector3 (x  ,  y  , 0 ));
			newVertices.Add( new Vector3 (x + 1 ,  y  , 0 ));
			newVertices.Add( new Vector3 (x + 1 ,  y-(1 - rate) , 0 ));
			newVertices.Add( new Vector3 (x  ,  y-1 , 0 ));
			
			newTriangles.Add((squareCount*4)+0);
			newTriangles.Add((squareCount*4)+1);
			newTriangles.Add((squareCount*4)+2);
			
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));

			colVertices.Add( new Vector3 (x  ,  y  , 0));
			colVertices.Add( new Vector3 (x  ,  y  , 1));
			colVertices.Add( new Vector3 (x + 1 ,  y-(1 - rate) , 1 ));
			colVertices.Add( new Vector3 (x +1 ,  y-(1-rate)  , 0 ));
			
			ColliderTriangles();
			
			colCount++;

			squareCount++;
		}
		else if(count == 5) {
			newVertices.Add( new Vector3 (x  ,  y  , 0 ));
			newVertices.Add( new Vector3 (x + 1 ,  y   , 0 ));
			newVertices.Add( new Vector3 (x + 1 ,  y-1 , 0 ));
			newVertices.Add( new Vector3 (x  ,  y-(1-rate) , 0 ));
			
			newTriangles.Add((squareCount*4)+0);
			newTriangles.Add((squareCount*4)+1);
			newTriangles.Add((squareCount*4)+3);
			
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));

			colVertices.Add( new Vector3 (x +1 ,  y  , 0));
			colVertices.Add( new Vector3 (x +1  ,  y  , 1));
			colVertices.Add( new Vector3 (x  ,  y-(1 - rate) , 1 ));
			colVertices.Add( new Vector3 (x ,  y-(1-rate)  , 0 ));
			
			ColliderTriangles();
			
			colCount++;

			squareCount++;
		}
		else if (count == 6) {
			newVertices.Add( new Vector3 (x  ,  y  , 0 ));
			newVertices.Add( new Vector3 (x+1  , y    , 0 ));
			newVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 0 ));
			newVertices.Add( new Vector3 (x  ,  y-1 , 0 ));
			
			newTriangles.Add((squareCount*4)+0);
			newTriangles.Add((squareCount*4)+1);
			newTriangles.Add((squareCount*4)+2);
			
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));

			colVertices.Add( new Vector3 (x  ,  y  , 0));
			colVertices.Add( new Vector3 (x  ,  y  , 1));
			colVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 1 ));
			colVertices.Add( new Vector3 (x+0.5f  ,  y-0.5f  , 0 ));
			
			ColliderTriangles();
			colCount++;
			
			colVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 0 ));
			colVertices.Add( new Vector3 (x+0.5f  ,  y-0.5f  , 1 ));
			colVertices.Add( new Vector3 (x+1  ,  y  , 1 ));
			colVertices.Add( new Vector3 (x+1 ,  y  , 0 ));
			
			ColliderTriangles();
			
			colCount++;

			squareCount++;
		}
		else if (count == 7) {
			newVertices.Add( new Vector3 (x  ,  y  , 0 ));
			newVertices.Add( new Vector3 (x+1  , y    , 0 ));
			newVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 0 ));
			newVertices.Add( new Vector3 (x+1  ,  y-1 , 0 ));
			
			newTriangles.Add((squareCount*4)+1);
			newTriangles.Add((squareCount*4)+3);
			newTriangles.Add((squareCount*4)+2);
			
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));

			colVertices.Add( new Vector3 (x + 1  ,  y-1  , 0));
			colVertices.Add( new Vector3 (x + 1 ,  y-1  , 1));
			colVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 1 ));
			colVertices.Add( new Vector3 (x+0.5f  ,  y-0.5f  , 0 ));
			
			ColliderTriangles();
			colCount++;
			
			
			colVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 0 ));
			colVertices.Add( new Vector3 (x+0.5f  ,  y-0.5f  , 1 ));
			colVertices.Add( new Vector3 (x+1  ,  y  , 1 ));
			colVertices.Add( new Vector3 (x+1 ,  y  , 0 ));
			
	ColliderTriangles();
			
			colCount++;

			squareCount++;
		}
		else if (count == 8) {
			newVertices.Add( new Vector3 (x  ,  y  , 0 ));
			newVertices.Add( new Vector3 (x  , y    , 0 ));
			newVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 0 ));
			newVertices.Add( new Vector3 (x  ,  y-1 , 0 ));
			
			newTriangles.Add((squareCount*4)+1);
			newTriangles.Add((squareCount*4)+2);
			newTriangles.Add((squareCount*4)+3);
			
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));

			colVertices.Add( new Vector3 (x  ,  y-1  , 0));
			colVertices.Add( new Vector3 (x  ,  y-1  , 1));
			colVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 1 ));
			colVertices.Add( new Vector3 (x+0.5f  ,  y-0.5f  , 0 ));
			
			ColliderTriangles();
			colCount++;
			
			colVertices.Add( new Vector3 (x + 0.5f ,  y-0.5f , 0 ));
			colVertices.Add( new Vector3 (x+0.5f  ,  y-0.5f  , 1 ));
			colVertices.Add( new Vector3 (x  ,  y  , 1 ));
			colVertices.Add( new Vector3 (x ,  y  , 0 ));
			
	ColliderTriangles();
			
			colCount++;

			squareCount++;
		}
	}

	void SmoothSquare(int x, int y, Vector2 texture, float rate, float brate) {
			newVertices.Add( new Vector3 (x  ,  y-rate  , 0 ));
			newVertices.Add( new Vector3 (x + 1 ,  y -brate, 0 ));
			newVertices.Add( new Vector3 (x + 1 ,  y-1 , 0 ));
			newVertices.Add( new Vector3 (x  ,  y-1 , 0 ));
			
			newTriangles.Add(squareCount*4);
			newTriangles.Add((squareCount*4)+1);
			newTriangles.Add((squareCount*4)+3);
			newTriangles.Add((squareCount*4)+1);
			newTriangles.Add((squareCount*4)+2);
			newTriangles.Add((squareCount*4)+3);
			
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
			newUV.Add(new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
			newUV.Add(new Vector2 (tUnit * texture.x, tUnit * texture.y));
			
			if(Block(x,y+1)==0){
				colVertices.Add( new Vector3 (x  ,  y - rate  , 1));
				colVertices.Add( new Vector3 (x + 1 ,  y - brate  , 1));
				colVertices.Add( new Vector3 (x + 1 ,  y - brate, 0 ));
				colVertices.Add( new Vector3 (x  ,  y - rate  , 0 ));
				
				ColliderTriangles();
				
				colCount++;
			}
			
			//bot
			if(Block(x,y-1)==0){
				colVertices.Add( new Vector3 (x  ,  y -1 , 0));
				colVertices.Add( new Vector3 (x + 1 ,  y -1 , 0));
				colVertices.Add( new Vector3 (x + 1 ,  y -1 , 1 ));
				colVertices.Add( new Vector3 (x  ,  y -1 , 1 ));
				
				ColliderTriangles();
				colCount++;
			}
			
			//left
			if(Block(x-1,y)==0){
				colVertices.Add( new Vector3 (x  ,  y -1 , 1));
				colVertices.Add( new Vector3 (x  ,  y  , 1));
				colVertices.Add( new Vector3 (x  ,  y  , 0 ));
				colVertices.Add( new Vector3 (x  ,  y -1 , 0 ));
				
				ColliderTriangles();
				
				colCount++;
			}
			
			//right
			if(Block(x+1,y)==0){
				colVertices.Add( new Vector3 (x +1 ,  y   , 1));
				colVertices.Add( new Vector3 (x +1 ,  y  , 0));
				colVertices.Add( new Vector3 (x +1 ,  y -1 , 0 ));
				colVertices.Add( new Vector3 (x +1 ,  y-1  , 1 ));
				
				ColliderTriangles();
				
				colCount++;
			}
			
			squareCount++;
	}

	void ColliderTriangles(){
		colTriangles.Add(colCount*4);
		colTriangles.Add((colCount*4)+1);
		colTriangles.Add((colCount*4)+3);
		colTriangles.Add((colCount*4)+1);
		colTriangles.Add((colCount*4)+2);
		colTriangles.Add((colCount*4)+3);
	}
}

[21337-unity+before.png|21337]

before changes on script

[21339-unity+smoothing.png|21339]

after

Is this the right way or would the performance be too slow? Is an obvious better way? (By maybe setting meshes vertices by Perlin Noise, if it´s even possible). Because I have otherwise no idea, what to do. I would really appreciate your support! :slight_smile:

Your code base will expand a lot. I would strongly suggest reading a book like “Clean Code: A Handbook of Agile Software Craftsmanship”. Other vise you will end up with problems increase exponentially with your code base.
This is not an exact answer but it will help you! Good luck!

I have made a lot of progress and implemented a 3D marching cubed algorithm. Of course there are still little things not working correctly yet. I would like you guys to maybe have a look. :wink: Marching Cubes terrain deformation