- Home /
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);
}
}
}
}
}
Have you tried generating a small test map, and inserting Debug.Log lines so you know if all parts of you code are reached, and if they return the right values?
it loops even a lot when doing 10x10. I have an amazing computer and 100x100 (what it's set on) causes it to lag. it has debugged at least 30,000 frames I assume at start.
Yes, that's nice, but it doesn't answer my question :) $$anonymous$$eep in $$anonymous$$d that even a 10x10x10 array consists of 1000 elements.
Answer by UnityStuff · Jun 24, 2015 at 08:01 PM
Line 25, if (x2 != 0 || y2 != 0)
shouldn't that be if (x2 != x || y2 != y)
Answer by Valnor · Jun 24, 2015 at 10:35 AM
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.
the calculate walls thing should do that. what did I do wrong? calculate walls should see what blocks around the original block are filled.
try changing if (neighbors > 6 || neighbors == 0)
to if (neighbors > 6 || neighbors <= 0)
it could be skipping a step if it's more or less than 0, not sure why it would go below 0 though.
Your answer
Follow this Question
Related Questions
Make object block a raycast 1 Answer
map generation issues 0 Answers
Fill bounded grid blocks 0 Answers
This script really makes my game lag! 1 Answer
Efficient grid system 1 Answer