I tried to program a map generator using a seed that then generates a noise map. I can successfully generate noise maps without errors:
The next step was to step through the array of floats and then place a tile based on those values. Since they were all generated in one spot, I added a variable that should provide space between the parts.
problem is that sometimes it doesn't work, and the tiles are spawned into each other.
Some Examples:
Strange holes have appeared in the map
Examples:
I don't quite understand why and would be very grateful if you could help me
My code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Analytics;
using UnityEngine.UI;
public class MapGenv2 : MonoBehaviour
{
public int mapWidth = 50;
public int mapHeight = 50;
public RawImage mapImage;
public string seed = "seed";
public Vector3 offset;
public float spaceInBetweenTiles = 0.1f;
public float[,] GenerateNoiseMap(int width, int height, string seed, Vector3 offset)
{
float[,] noiseMap = new float[width, height];
System.Random prng = new System.Random(seed.GetHashCode());
Vector2[] octaveOffsets = new Vector2[6];
float maxPossibleHeight = 0;
float amplitude = 1;
float frequency = 1;
float noiseHeight = 0;
float maxLocalNoiseHeight = float.MinValue;
float minLocalNoiseHeight = float.MaxValue;
float halfWidth = width / 2f;
float halfHeight = height / 2f;
for (int i = 0; i < 6; i++)
{
float offsetX = prng.Next(-100000, 100000) + offset.x;
float offsetY = prng.Next(-100000, 100000) + offset.y;
octaveOffsets[i] = new Vector2(offsetX, offsetY);
maxPossibleHeight += amplitude;
amplitude *= 0.5f;
}
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
amplitude = 1;
frequency = 1;
noiseHeight = 0;
for(int i = 0; i < 6; i++)
{
float sampleX = (x - halfWidth + octaveOffsets[i].x) / 100 * frequency;
float sampleY = (y - halfHeight + octaveOffsets[i].y) / 100 * frequency;
float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
noiseHeight += perlinValue * amplitude;
amplitude *= 0.5f;
frequency *= 2;
}
if(noiseHeight > maxLocalNoiseHeight)
{
maxLocalNoiseHeight = noiseHeight;
}
else if(noiseHeight < minLocalNoiseHeight)
{
minLocalNoiseHeight = noiseHeight;
}
noiseMap[x, y] = noiseHeight;
}
}
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
}
}
return noiseMap;
}
public GameObject holder;
public GameObject plain;
public GameObject mountain;
public GameObject water;
public GameObject forest;
public float plainHeight = 0.5f;
public float mountainHeight = 0.8f;
public float waterHeight = 0.2f;
public float forestHeight = 0.6f;
public void gen()
{
//delete old map
foreach (Transform child in holder.transform)
{
Destroy(child.gameObject);
}
float [,] noiseMap = GenerateNoiseMap(mapWidth, mapHeight, seed, offset);
for( int y = 0; y < mapHeight; y++)
{
for (int x = 0; x < mapWidth; x++)
{
float currentHeight = noiseMap[x, y];
Vector3 pos = new Vector3(-mapWidth / 2 + x + spaceInBetweenTiles * x, 0, -mapHeight / 2 + y + spaceInBetweenTiles * y);
if (currentHeight < waterHeight)
{
Instantiate(water, pos, Quaternion.identity, holder.transform);
}
else if (currentHeight < plainHeight)
{
Instantiate(plain, pos, Quaternion.identity, holder.transform);
}
else if (currentHeight < forestHeight)
{
Instantiate(forest, pos, Quaternion.identity, holder.transform);
}
else if (currentHeight < mountainHeight)
{
Instantiate(mountain, pos, Quaternion.identity, holder.transform);
}
}
}
Texture2D texture = new Texture2D(mapWidth, mapHeight);
Color[] colorMap = new Color[mapWidth * mapHeight];
for (int y = 0; y < mapHeight; y++)
{
for (int x = 0; x < mapWidth; x++)
{
colorMap[y * mapWidth + x] = Color.Lerp(Color.black, Color.white, noiseMap[x, y]);
}
}
texture.SetPixels(colorMap);
texture.Apply();
mapImage.texture = texture;
}
}




