使用柏林噪声随机创建像素地图

时间:2024-03-14 16:31:25

主要参考:Unity中使用柏林噪声生成地图

使用柏林噪声随机创建像素地图

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class RandomCreatMapByPerlinNoise : MonoBehaviour
{
    [SerializeField] Vector2Int mapSize = new Vector2Int(50, 50);

    [SerializeField] float maxHeight = 10;

    [SerializeField] float riseParame = 10f;

    [SerializeField] bool isSmoothness = false;

    GameObject[,] mapCubes;

    void Awake()
    {
        mapCubes = new GameObject[mapSize.x, mapSize.y];
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
            StartCoroutine(CreateMapDelay());
        else if (Input.GetMouseButtonDown(1))
            DestrotMap();
    }

    void DestrotMap()
    {
        for (int i = 0; i < mapSize.x; i++)
        {
            for (int j = 0; j < mapSize.y; j++)
            {
                if (mapCubes[i, j] != null && mapCubes[i, j].activeSelf)
                    mapCubes[i, j].SetActive(false);
            }
        }
    }

    IEnumerator CreateMapDelay()
    {
        float[,] posY = RandomPosY(mapSize, riseParame);

        for (int x = 0; x < mapSize.x; x++)
        {
            for (int z = 0; z < mapSize.y; z++)
            {
                if (mapCubes[x, z] == null)
                {
                    mapCubes[x, z] = GameObject.CreatePrimitive(PrimitiveType.Cube);
                    mapCubes[x, z].transform.SetParent(transform);
                }

                GameObject cube = mapCubes[x, z];
                if (!cube.activeSelf)
                    cube.SetActive(true);

                float y = posY[x, z] * maxHeight;
                if (!isSmoothness)
                    y = Mathf.Round(y);

                cube.transform.localPosition = new Vector3(x, y, z);

                Color color = Color.black;

                if (posY[x, z] > 0.9f)
                {
                    color = Color.white;
                }
                else if (posY[x, z] > 0.3f)
                {
                    color = Color.green;
                }
                else if (posY[x, z] > 0.2f)
                {
                    color = Color.blue;
                }
                else if (posY[x, z] > 0.1f)
                {
                    color = Color.yellow;
                }
                cube.GetComponent<MeshRenderer>().material.color = color;
            }
            yield return null;
        }
    }

    float[,] RandomPosY(Vector2Int size, float rise)
    {
        float[,] result = new float[size.x, size.y];
        float xSample = 0;
        float zSample = 0;

        //随机种子
        float seedX = Random.value;
        float seedZ = Random.value;

        for (int x = 0; x < size.x; x++)
        {
            for (int z = 0; z < size.y; z++)
            {
                //Y值与X/Z值相关
                xSample = (1.0f * x / mapSize.x + seedX) * 0.5f * rise;
                zSample = (1.0f * z / mapSize.y + seedZ) * 0.5f * rise;
                //柏林噪声
                result[x,z] = Mathf.PerlinNoise(xSample, zSample);
            }
        }
        return result;
    }

}