- Home /
Perlin noise not being changed runtime
I have written some code to generate some terrain. It uses perlin noise to decide what type of tile to spawn. I am happy with the results of using perlin noise, but there is a problem. I would assume that with this code a different terrain would be generated, because the perlin noise generated would be different. However this doesn't work, so is there a problem in the code? Or is the perlin noise cached and I have to generate a new one at runtime? Here is my code:
using UnityEngine;
using System.Collections;
public class TerrainGeneration : MonoBehaviour {
public float tileWidth;
public GameObject grass;
public GameObject dirt;
public GameObject water;
private float[,] terrainArray;
// Use this for initialization
void Start () {
Vector2 currentPos = (Vector2)transform.position;
for (float x = 0; x < 100; x++) {
for (float y = 0; y < 100; y++) {
float noise = Mathf.PerlinNoise (x / 10f, y / 10f);
if (noise < 0.2) {
Instantiate (water, currentPos, transform.rotation);
} else if (noise > 0.2 && noise < 0.8) {
Instantiate (grass, currentPos, transform.rotation);
} else {
Instantiate (dirt, currentPos, transform.rotation);
}
currentPos = currentPos + new Vector2 (tileWidth, 0);
}
currentPos = new Vector2 (0, currentPos.y + tileWidth);
}
}
// Update is called once per frame
void Update () {
}
}
Answer by Eno-Khaon · Apr 17, 2016 at 08:13 PM
Part of the intent of the Perlin Noise algorithm is that, given the same inputs, you will see the same outputs every time. For example, this allows you to use the algorithm to generate an infinite environment without having to save infinite data to the hard drive.
Your inputs for the noise are two floating point numbers, x and y. They effectively range from 0 to 9.9, by your implementation.
Because the noise algorithm will give you consistent outputs for consistent inputs, you can expect to see the same results every time right now.
What this means is that you can modify your scale for your for loops and see different outputs as a result.
An example of this could look something like:
public float xOffset;
public float yOffset;
// ...
for(float x = xOffset; x < 100 + xOffset; x++)
{
for(float y = yOffset; y < 100 + yOffset; y++)
{
// ...
}
}
In this form, your scale would remain unchanged from its current state, so all changes would come from the offsets alone. That said, scaling could also be modified with further tweaks, such as:
for(float x = xOffset; x < (100 * increment) + xOffset; x+=increment)
Answer by tanoshimi · Apr 17, 2016 at 08:07 PM
If you always sample the same co-ordinates, you'll always get the same result. You need to apply a random offset, something like:
Vector2 offset = new Vector2(Random.Range(0,100f),Random.Range(0,100f));
float noise = Mathf.PerlinNoise (x / 10f + offset.x, y / 10f + offset.y);
...