I saw a lot of people asking how to do procedural caves, so I decided to create a thread about this.
IMPORTANT: THIS IS NOT A PROCEDURAL TERRAIN GENERTAION, JUST HOW TO MAKE A GIGANT CAVE SYSTEM
First, create a cube. Name it what you want, make it a prefab and delete it from the scene. This will be the voxel.
Next create a empty game object. Im going to name it CaveGenerator (Yeah, very original) and add to it a new script Im also going to name it CaveGenerator.
Okay, so first the variables:
public float noiseScale = 0.05f;
[Range 0,1]public float noiseMin = 0.5f;
[Range 0,1]public float noiseMax = 0.65f;
public GameObject cube;
public float size = 30f
So lets see them one by one:
-The noise scale is the size of the caves, the caves will be exactly the same but bigger or smaller.
-The noise min value is the smallest number that can have a voxel, if smaller, it wont appear.
-The noise max value is the same as the noise min value bu setting a max value a voxel can have, if bigger, It wont appear.
-The cube gameobject is the prefab we created. We will place it if the noise values are correct.
-The size is how much big is going to be our cave system. Be careful, big sizes cause unity crashing.
Is a good idea to make the variables pubic so you can edit then in the inspector.
Second, some 3D noise function:
float Perlin3D(int X, int Y, int Z)
{
float x =(float)X;
float y =(float)Y;
float z =(float)Z;
x *= noiseScale;
y *= noiseScale;
z *= noiseScale;
float xy = Mathf.PerlinNoise(x,y);
float xz = Mathf.PerlinNoise(x,z);
float yx = Mathf.PerlinNoise(y,x);
float yz = Mathf.PerlinNoise(y,z);
float zx = Mathf.PerlinNoise(z,x);
float zy = Mathf.PerlinNoise(z,y);
return (xy+xz+yx+yz+zx+zy) / 6
}
This noise function transforms 2D noise into 3D noise, so we can generate our caves.
Okay, next we are going to genetate the actual caves:
First, in the Start void:
void Start()
{
GenerateCaves();
}
Now we are going to create the GenerateCaves void:
void GenerateCaves()
{
for(int x = 0; x < size; x++)
{
for(int y = 0; y < size; y++)
{
for(int z = 0; z < size; z++)
{
if(Perlin3D(x,y,z)<noiseMax)
{
if(Perlin3D(x,y,z)>noiseMin)
{
//A voxel can be here
Instantiate(cube,new Vector3((float)x,(float)y,(float)z), Quaternion.identity);
}
}
}
}
}
}
Now put the Cube prefab into the cube field, change th nlise values as you lika and hit play! After some time the cave will be there! Since the cubes have a collider you can make a character controller and walk trough them!
Some very important things:
If you set the scale to 0, there wont ve any caves.
A very big size causes unity to break.
Is posible to edit the script so you can get interesting caves.