Ok, complicated question… I am trying to create a smooth voxel sphere shaped “planet,” which can be edited in runtime, and have different materials, which have different names, so when you destroy a piece of material, it puts the same material into your inventory, so you can have mineral veins deep inside the planet to dig, somewhat like Empyrion Galactic Survival, or space engineers. I have basic knowledge of how minecraft style voxels work, but the smooth terrain system doesn’t seem to work this way. Any help would be greatly appreciated. Thanks in advance!
So first we find your World class. Here I make so assumtions as I don’t know what this class actually looks like, but I guess it starts something along these lines:
public class World {
...
public static World currentWorld;
public int chunkWidth;
public int chunkHeight;
...
}
We want to leave as much as we can the same, so we don’t have to change to much other stuff, so I will leave chunkHeight in there, though it would be sensible to set chunkWidth and chunkHeight to the same value.
I will add a value ‘radius’ which will be the radius of the world we create.
public class World {
...
public static World currentWorld;
public int chunkWidth;
public int chunkHeight;
public float radius;
...
}
Then in the script you attached as a text file, we need to make some changes, so it doesn’t just build the bottom layer of blocks as it is doing atm. Here I have changed the for loops in start, and the byte array ‘map’ is now a float array to be compatible with the project you found:
void Start () {
meshRenderer = GetComponent<MeshRenderer>();
meshCollider = GetComponent<MeshCollider>();
meshFilter = GetComponent<MeshFilter>();
map = new float[World.currentWorld.chunkWidth, World.currentWorld.chunkHeight, World.currentWorld.chunkWidth];
int centreXZ = World.currentWorld.chunkWidth/2;
int centreY = World.currentWorld.chunkHeight/2;
int distSqr;
for (int x = 0; x < World.currentWorld.chunkWidth; x++)
{
for (int y = 0; y < World.currentWorld.chunkHeight; y++)
{
for (int z = 0; z < World.currentWorld.chunkWidth; z++)
{
distSqr = ((x-centreXZ)*(x-centreXZ) + (y-centreY)*(y-centreY) + (z-centreXZ)*(z-centreXZ));
distSqr -= World.currentWorld.radius*World.currentWorld.radius;
if(distSqr >= 0) continue; //skip it if ouside our radius
//otherwise set it to 1 if completely contained, or a float value if on edge
distSqr = World.currentWorld.radius-Mathf.Sqrt(distSqr);
float val = Mathf.Lerp(0, 1, -distSqr);
map[x, y, z] = val;
}
}
}
}
the last bit to change is using the project you found, we should simply be able to do:
void Start () {
//...
//other stuff
//...
MarchingCubes.SetTarget(0.5f);
MarchingCubes.SetModeToCubes();
visualMesh = MarchingCubes.CreateMesh(map);
meshFilter.mesh = visualMesh;
meshCollider.sharedMesh = visualMesh;
}
Make sure you remove the ‘CreateVisualMesh();’ call!
I haven’t tested this, so it’s likely there is some problem (sorry) but feel free to ask more in the comments!
Scribe