Hey, thanks for the reply. No, I’m not trying to make a Minecraft-like world. I’m trying to make procedural terrain except spherical, so it looks like a planet. I’m currently using a cube model split up into 24 chunks and turning it into a sphere. (“sphere-ifying” it, if you will. pictures in original post)
24 chunks can only make a very small planet, though. So what I’m asking is, how can I procedurally generate a cube split up into, let’s say, 100 parts. (my original 24 part cube was done manually in blender)
I’ll take a look but I’m not sure how much this is going to help me since I’m not using voxels nor looking to make a Minecraft clone.
@everyone If my explanations are confusing maybe it’ll make sense if you look at the code. Here’s what I got so far:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using CoherentNoise.Generation.Fractal;
using System.IO;
using System;
public class Planet : MonoBehaviour
{
private Mesh mesh;
private Vector3[] vertices;
public float radius = 1f;
public float noiseModifier = 0.1f;
public List<GameObject> chunks = new List<GameObject>();
private MeshCollider meshCollider;
public AnimationCurve heightCurve;
public int seed;
void Start()
{
GeneratePlanet();
}
public void GeneratePlanet()
{
chunks = new List<GameObject> ();
for (int c = 0; c < 24; c++) {
chunks.Add(GameObject.Find("c"+(c+1)));
}
PinkNoise noise = new PinkNoise(seed);
for (int c = 0; c < chunks.Count; c++) {
mesh = chunks[c].GetComponent<MeshFilter>().sharedMesh;
//meshCollider = GetComponent<MeshCollider>();
vertices = mesh.vertices;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] = (vertices[i].normalized * (radius + heightCurve.Evaluate(noise.GetValue(vertices[i].normalized)) * noiseModifier));
}
mesh.vertices = vertices;
mesh.RecalculateNormals();
mesh.RecalculateBounds();
if (chunks[c].GetComponent<MeshCollider>() == null)
chunks[c].AddComponent<MeshCollider>();
chunks[c].GetComponent<MeshCollider>().sharedMesh = mesh;
}
}
}
Cube model I’m using: [download .blend]
To set it up and see, place down the cube at 0, 0, 0, then add the Planet script to the parent object of all the chunks. (“SplitCube”, should be the name of the object). In the inspector set Noise Modifier to 3, Radius to 75, and then pick one of the defaults from Height Curve.
Here’s my attempt at creating a semi-procedural cube, (split up into many parts) to then “sphere-ify”, just like I did with the blender cube model:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using CoherentNoise.Generation.Fractal;
using System.IO;
using System;
public class DynamicPlanet : MonoBehaviour
{
private Mesh gameMesh;
private Vector3[] vertices;
public float radius = 1f;
public float noiseModifier = 0.1f;
public List<GameObject> chunks = new List<GameObject>();
public int chunkCount = 0;
private MeshCollider meshCollider;
public AnimationCurve heightCurve;
public int seed;
public GameObject chunk;
public Transform front;
public Transform top;
public int offsetIncrement;
void Start() {
GenerateCube();
}
public void GenerateCube() {
GenerateSide();
}
private int id = 1;
public void GenerateSide() {
Vector3 offset = new Vector3(0, 0, 0);
//multiplier switches every other plane spawned, so that the origin point is always in the center
int multiplier = -1;
for (int x = 0; x < chunkCount; x++) {
SpawnPlane (new Vector3(offset.x * multiplier, offset.y, 4), "c"+id);
id++;
for (int y = 0; y < chunkCount; y++) {
SpawnPlane (new Vector3(offset.x * multiplier, (offset.y+2), 4), "c"+id);
id++;
offset.y += offsetIncrement;
}
if (multiplier == -1) {
offset.x += offsetIncrement;
}
offset.y = 0;
multiplier = multiplier * -1;
}
GeneratePlanet ();
}
public void SpawnPlane(Vector3 offset, String id) {
GameObject c = (GameObject)Instantiate (chunk, transform.position, Quaternion.identity);
Mesh cMesh = c.GetComponent<MeshFilter> ().mesh;
Vector3[] verts = cMesh.vertices;
for (int v = 0; v < verts.Length; v++) {
verts [v].x += offset.x;
verts [v].y += offset.y;
verts [v].z += offset.z;
}
cMesh.vertices = verts;
c.name = id;
chunks.Add (c);
}
public void GeneratePlanet() {
for (int c = 0; c < chunks.Count; c++) {
chunks[c] = GameObject.Find("c"+(c+1));
}
PinkNoise noise = new PinkNoise(seed);
for (int c = 0; c < chunks.Count; c++) {
gameMesh = chunks[c].GetComponent<MeshFilter>().sharedMesh;
vertices = gameMesh.vertices;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] = (vertices[i].normalized * (radius + heightCurve.Evaluate(noise.GetValue(vertices[i].normalized)) * noiseModifier));
}
gameMesh.vertices = vertices;
gameMesh.RecalculateNormals();
gameMesh.RecalculateBounds();
if (chunks [c].GetComponent<MeshCollider> () == null) {
chunks [c].AddComponent<MeshCollider> ();
}
chunks[c].GetComponent<MeshCollider>().sharedMesh = gameMesh;
}
}
}
Basically, I’m just taking a flat plane I made in Blender, (the plane has lots of vertices, though, for detailed terrain) and spawning a lot of them next to each other make a larger and split up side of the cube. Except instead of moving the object position when spawning, I offset all the vertice positions so that all the planes can have the same origin point.
This works fine, I get 1 side of the cube, and thus a partial planet. Now I’m not sure how to go about getting all the other sides of the cube to generate. I mean, sure I could just mess around with numbers until the sides align but the goal here is to have a procedural planet that I can adjust the size of and still work fine.