Trying to remove blocks with no neighbors in cave generation code, so there are no floating blocks.

Hello!

Recently I was following a tutorial and tried to generate a random cave by placing points and expanding on them. I am following Sebastian Lague’s tutorial but I tweaked it a little.

The issue is at one point I check the neighbors and if there are no surrounding blocks, I want to remove the block.

Can someone look at this code and tell me what is wrong? Any and all help will be greatly appreciated.

using UnityEngine;
using System.Collections;

public class MapGenerator : MonoBehaviour {

	public int width;
	public int height;
	
	private enum Cubes
	{
		Yes,
		No
	};
	private Cubes [,] map;
	
	[Range (0, 100)]
	public int fillFrequency;
	
 	private int CalculateAmountOfWalls (int x, int y) {
		int neighbors = 0;
		for (int x2 = x - 1; x2 < x + 2; x2 ++)
		{
			for (int y2 = y - 1; y2 < y + 2; y2 ++)
			{
				if (x2 != 0 || y2 != 0)
				{
					if (x > 0 && x < width - 1 && y > 0 && y < height - 1)
					{
						if (map [x2, y2] == Cubes.Yes)
						{
							neighbors ++;
						}
					}
					else
					{
						if (x <= 0 && y <= 0) 
						{
							if (x2 > -1 && y2 > -1)
							{
								if (map [x2, y2] == Cubes.Yes)
								{
									neighbors ++;
								}
							}
						}
						if (x >= width && y <= 0) 
						{
							if (x2 < 1 && y2 > -1)
							{
								if (map [x2, y2] == Cubes.Yes)
								{
									neighbors ++;
								}
							}
						}
						if (x <= 0 && y >= height) 
						{
							if (x2 > -1 && y2 < 1)
							{
								if (map [x2, y2] == Cubes.Yes)
								{
									neighbors ++;
								}
							}
						}
						if (x >= width && y >= height) 
						{
							if (x2 < 1 && y2 < 1)
							{
								if (map [x2, y2] == Cubes.Yes)
								{
									neighbors ++;
								}
							}
						}
					}
				}
			}
		}
		return neighbors;
	}
	
	void Start () {
		CreateMap ();
	}
	
	void CreateMap () {
		map = new Cubes [width, height];
		FillMap ();
	}
	
	void FillMap () {
		for (int w = 0; w < width; w ++)
		{
			for (int h = 0; h < height; h ++)
			{
				map [w, h] = Cubes.No;
			}
		}
		for (int p = 0; p < width * height / 100 * fillFrequency; p ++)	
		{
			int x = Random.Range (0, width);
			int y = Random.Range (0, height);
			map [x, y] = Cubes.Yes;
		}
		for (int i = 0; i < 8; i ++)
		{
			SmoothMap ();
		}
	}
	
	void SmoothMap () {
		for (int x = 0; x < width; x ++)
		{
			for (int y = 0; y < height; y ++)
			{
				int neighbors = CalculateAmountOfWalls (x, y);
				if (neighbors > 6 || neighbors == 0)
				{
					map [x, y] = Cubes.No;
				}
			}
		}
	}
	
	void OnDrawGizmos () {
		for (int x = 0; x < width; x ++)
		{
			for (int y = 0; y < height; y ++)
			{
				Vector2 pos = new Vector2 (x + 0.5f - width / 2, y + 0.5f - height / 2);
				if (map != null)
				{
					if (map [x, y] == Cubes.Yes)
					{
						Gizmos.color = Color.red;
					}
					else
					{
						Gizmos.color = Color.green;
					}
					Gizmos.DrawCube (pos, Vector3.one);
				}
			}
		}
	}
}

you could make a small script that raycasts at half the measure of the block in each direction, if something is found by the raycast kill the script, but if nothing is found on any of the 6 sides… kill object, and have this script in each block, it would hurt initial load time possibly, but it would allow for the rule of “if not touching any one just die already” without tampering with the main generation code.

Line 25, if (x2 != 0 || y2 != 0) shouldn’t that be if (x2 != x || y2 != y)