Unity中利用柏林噪音生成随机地图

利用柏林噪音生成随机地图<2/2/2018>

什么是柏林噪音?(请自行百度)Perlin噪声 ( Perlin noise )指由Ken Perlin发明的自然噪声生成算法 。

原理学习可以参考:http://postd.cc/understanding-perlin-noise/

此处我们主要参考的是http://kan-kikuchi.hatenablog.com/entry/PerlinNoise的柏林噪音生成方法:

先上效果图:


然后上kikuchi写的柏林噪音脚本:

//  RandomMapMaker.cs
//  http://kan-kikuchi.hatenablog.com/entry/PerlinNoise
//
//  Created by kan kikuchi on 2016.3.14.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// ランダムにマップを生成する
/// </summary>
public class RandomMapMaker : MonoBehaviour
{

    //シード
    private float _seedX, _seedZ;

    //マップのサイズ
    [SerializeField]
    [Header("------実行中に変えれない------")]
    private float _width = 50;
    [SerializeField]
    private float _depth = 50;

    //コライダーが必要か
    [SerializeField]
    private bool _needToCollider = false;

    //高さの最大値
    [SerializeField]
    [Header("------実行中に変えられる------")]
    private float _maxHeight = 10;

    //パーリンノイズを使ったマップか
    [SerializeField]
    private bool _isPerlinNoiseMap = true;

    //起伏の激しさ
    [SerializeField]
    private float _relief = 15f;

    //Y座標を滑らかにするか(小数点以下をそのままにする)
    [SerializeField]
    private bool _isSmoothness = false;

    //マップの大きさ
    [SerializeField]
    private float _mapSize = 1f;

    //=================================================================================
    //初期化
    //=================================================================================

    private void Awake()
    {
        //マップサイズ設定
        transform.localScale = new Vector3(_mapSize, _mapSize, _mapSize);

        //同じマップにならないようにシード生成
        _seedX = Random.value * 100f;
        _seedZ = Random.value * 100f;

        //キューブ生成
        for (int x = 0; x < _width; x++)
        {
            for (int z = 0; z < _depth; z++)
            {

                //新しいキューブ作成、平面に置く
                GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
                cube.transform.localPosition = new Vector3(x, 0, z);
                cube.transform.SetParent(transform);

                if (!_needToCollider)
                {
                    Destroy(cube.GetComponent<BoxCollider>());
                }

                //高さ設定
                SetY(cube);
            }
        }
    }

    //インスペクターの値が変更された時
    private void OnValidate()
    {
        //実行中でなければスルー
        if (!Application.isPlaying)
        {
            return;
        }

        //マップの大きさ設定
        transform.localScale = new Vector3(_mapSize, _mapSize, _mapSize);

        //各キューブのY座標変更
        foreach (Transform child in transform)
        {
            SetY(child.gameObject);
        }
    }

    //キューブのY座標を設定する
    private void SetY(GameObject cube)
    {
        float y = 0;

        //パーリンノイズを使って高さを決める場合
        if (_isPerlinNoiseMap)
        {
            float xSample = (cube.transform.localPosition.x + _seedX) / _relief;
            float zSample = (cube.transform.localPosition.z + _seedZ) / _relief;

            float noise = Mathf.PerlinNoise(xSample, zSample);

            y = _maxHeight * noise;
        }
        //完全ランダムで高さを決める場合
        else
        {
            y = Random.Range(0, _maxHeight);
        }

        //滑らかに変化しない場合はyを四捨五入
        if (!_isSmoothness)
        {
            y = Mathf.Round(y);
        }

        //位置設定
        cube.transform.localPosition = new Vector3(cube.transform.localPosition.x, y, cube.transform.localPosition.z);

        //高さによって色を段階的に変更
        Color color = Color.black;//岩盤っぽい色

        if (y > _maxHeight * 0.3f)
        {
            ColorUtility.TryParseHtmlString("#019540FF", out color);//草っぽい色
        }
        else if (y > _maxHeight * 0.2f)
        {
            ColorUtility.TryParseHtmlString("#2432ADFF", out color);//水っぽい色
        }
        else if (y > _maxHeight * 0.1f)
        {
            ColorUtility.TryParseHtmlString("#D4500EFF", out color);//マグマっぽい色
        }

        cube.GetComponent<MeshRenderer>().material.color = color;
    }

}


  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值