Unity|PerlinNoiseで自然なマップをランダム生成する

当ページのリンクには広告が含まれています。

Unity2Dのタイルマップ(Tilemap)でランダムなマップをPerlinNoiseを利用して作成してみます。

はじめに

Unityのバージョンは6000.5.2f1です。下記記事にてランダムなマップを生成してました。

記事内で作成したスクリプトは下記となっており、ランダムでタイルを選択しています。

using UnityEngine;
using UnityEngine.Tilemaps;


public class MapGenerate : MonoBehaviour
{
    [SerializeField] private Tilemap tilemap;
    [SerializeField] private int mapSize;
    [SerializeField] private Tile[] tiles;

    private void Start()
    {
        RandomMapGenerate();
    }

    private void RandomMapGenerate()
    {
        for (int y = 0; y < mapSize; y++)
        {
            for (int x = 0; x < mapSize; x++)
            {
                Tile tile = tiles[Random.Range(0, tiles.Length)];
                tilemap.SetTile(new Vector3Int(x - mapSize / 2, y - mapSize / 2, 0), tile);
            }
        }
    }
}

実行すると下記の様な形になります。

個々のタイルをランダムでセットしており、実際のマップとして考えた場合不自然な形なので、今回は自然な形に近いマップを「PerlinNoise」を利用して作成します。

作成開始

マップ生成のスクリプトを下記に変更します。高さをPerlinNoiseで生成、高さに応じてタイルをセットしています。

using UnityEngine;
using UnityEngine.Tilemaps;

[System.Serializable]
public struct TileData
{
    public Tile tile;

    public float minHeight;
    public float maxHeight;
}

public class MapGenerate : MonoBehaviour
{
    [SerializeField] private Tilemap tilemap;
    [SerializeField] private int mapSize;
    [SerializeField] private TileData[] tileDatas;

    private float scale = 5f;

    private void Start()
    {
        RandomMapGenerate();
    }

    private void RandomMapGenerate()
    {
        for (int y = 0; y < mapSize; y++)
        {
            for (int x = 0; x < mapSize; x++)
            {
                float xCoord = (float)x / mapSize  * scale;
                float yCoord = (float)y / mapSize  * scale;

                float height = Mathf.PerlinNoise(xCoord, yCoord);

                foreach (TileData tileData in tileDatas)
                {
                    if (height >= tileData.minHeight && height <= tileData.maxHeight)
                    {
                        tilemap.SetTile(new Vector3Int
                            (x - mapSize / 2, y - mapSize / 2, 0), tileData.tile);
                        break;
                    }

                }
            }
        }
    }
}

パラメータをセットします。Height(高さ)は0~1で割り当てます。

「PerlinNoise」を利用するとランダム値が波で作成されるのでアニメーション、地形などに利用できます。下記が公式リファレンスです。

実行すると下記の様な感じに。地形感がでます。

下記の様にランダム値を追加することで、実行するごとに違うマップを生成することが出来ます。

    private void RandomMapGenerate()
    {
        float random = Random.Range(0f, 100f);

        for (int y = 0; y < mapSize; y++)
        {
            for (int x = 0; x < mapSize; x++)
            {

                float xCoord = ((float)x+random) / mapSize * scale;
                float yCoord = ((float)y+random) / mapSize * scale;

                float height = Mathf.PerlinNoise(xCoord, yCoord);

                foreach (TileData tileData in tileDatas)
                {
                    if (height >= tileData.minHeight && height <= tileData.maxHeight)
                    {
                        tilemap.SetTile(new Vector3Int
                            (x - mapSize / 2, y - mapSize / 2, 0), tileData.tile);
                        break;
                    }
                }
            }
        }
    }

タイトルとURLをコピーしました