- Home /
How do I generate believable terrain for a 2D game using cubes?
Ok, I have a fairly simple code that spawns a moving block. It spawns them in a range.
 Instantiate (defaultground, Vector3 (transform.position.x, Random.Range(0,2.5), transform.position.z), transform.rotation);
What I want to do with this snippet code is to replace it with code that can set a "trend", ie. instead of randomly making blocks, making it go up and down in hills. How should I approach this?
Answer by Herman-Tulleken · Jul 21, 2011 at 10:14 AM
Check out this:
http://devmag.org.za/2009/04/25/perlin-noise/
Basically, you can generate Perlin noise, and use that to drive the vertical position of your cubes.
I am not sure what you want to do---is using Unity's terrain system an option? There are also plug-ins for generating procedural landscape.
Edit: Here is an version from the DevMag article translated to Unity to get you started. It is 1D only... read the article for an explanation.
Here is how it looks:
...Sorry, QATO's image thing does not want to work... here is the link:
http://www.devmag.org.za/examples/perlin_noise/terrain.png
 public class TerrainSpawn : MonoBehaviour 
 {
     public GameObject cubePrefab;
     public int cubesToGenerate = 20;
 
     float[] GetEmptyArray(int width)
     {
         return new float[width];
     }
 
     float[] GenerateWhiteNoise(int width)
     {
         float[] noise = GetEmptyArray(width);
 
         for (int i = 0; i < width; i++)
         {
             noise[i] = (float)Random.value;        
         }
 
         return noise;
     }
 
     float Interpolate(float x0, float x1, float alpha)
     {
        return x0 * (1 - alpha) + alpha * x1;
     }
 
 
     float[] GenerateSmoothNoise(float[] baseNoise, int octave)
     {
        int width = baseNoise.Length;     
        float[] smoothNoise = GetEmptyArray(width);     
        int samplePeriod = 1 << octave; // calculates 2 ^ k
        float sampleFrequency = 1.0f / samplePeriod;
      
        for (int i = 0; i < width; i++)
        {
           //calculate the horizontal sampling indices
           int sample_i0 = (i / samplePeriod) * samplePeriod;
           int sample_i1 = (sample_i0 + samplePeriod) % width; //wrap around
           float horizontal_blend = (i - sample_i0) * sampleFrequency;
           
           smoothNoise[i] = Interpolate(baseNoise[sample_i0],
                 baseNoise[sample_i1], horizontal_blend);          
        }
      
        return smoothNoise;
     }
 
     float[] GeneratePerlinNoise(float[] baseNoise, int octaveCount)
     {
         int width = baseNoise.Length;
         float[][] smoothNoise = new float[octaveCount][]; //an array of 2D arrays containing
         float persistance = 0.5f;
 
         //generate smooth noise
         for (int i = 0; i < octaveCount; i++)
         {
             smoothNoise[i] = GenerateSmoothNoise(baseNoise, i);
         }
 
         float[] perlinNoise = GetEmptyArray(width);
         float amplitude = 1.0f;
         float totalAmplitude = 0.0f;
 
         //blend noise together
         for (int octave = octaveCount - 1; octave >= 0; octave--)
         {
             amplitude *= persistance;
             totalAmplitude += amplitude;
 
             for (int i = 0; i < width; i++)
             {
                 perlinNoise[i] += smoothNoise[octave][i] * amplitude;
             }
         }
 
         //normalisation
         for (int i = 0; i < width; i++)
         {
             perlinNoise[i] /= totalAmplitude;
         }
 
         return perlinNoise;
     }
 
     public void Start()
     {
         float[] perlinNoise = GeneratePerlinNoise(GenerateWhiteNoise(cubesToGenerate), 5);
 
         for (int i = 0; i < cubesToGenerate; i++)
         {
             GameObject gObject = (GameObject) Instantiate(cubePrefab);
 
             gObject.transform.position = new Vector3(i, 4*perlinNoise[i], 0);
         }
     }        
 }
O$$anonymous$$. So using Perlin noise should be fine; you only need to generate 1D Perlin noise though. Here is a better article for the 1D case:
I'm not quite sure on how to make perlin noise in Unity. I only really know how to program things that directly relate to Unity.
O$$anonymous$$, I did a quick version for you. Play with the constants for different effects.
What do I change to make different ranges? I usually code in JavaScript so...
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                