Generating maps using Noisemap: Tiles are spawning in each other and weird spaces between tiles

Viewed 17

I tried to program a map generator using a seed that then generates a noise map. I can successfully generate noise maps without errors:

Then noise map

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.

  1. problem is that sometimes it doesn't work, and the tiles are spawned into each other.

    Some Examples:

    tree in mountain

    water in grass

    grass in mountain

  2. Strange holes have appeared in the map

    Examples:

    Image from the map

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;
    }
}

0 Answers
Related