孙广东 2017.3.27
http://blog.csdn.NET/u010019717
主要是利用Unity的 Mathf.PerlinNoise 函数(柏林噪声)的不同寻常的功能。
https://docs.unity3d.com/ScriptReference/Mathf.PerlinNoise.html 其中一个实例代码是生成 柏林噪声图片。 第二个实例是动画效果(看似y轴的随机运动,对随机的动画来讲很好啊!)。
这样设置 得到:
1、Mathf.PerlinNoise 函数的返回值是 0~1
2、一样的输入,输出也必将是一样的: 比如下面的测试,输出一直是 0.4652731
void Update()
{
float height = heightScale *Mathf.PerlinNoise(5f/*Time.time * xScale*/, 0.0F);
3、他的代码思路就是 100 *100个方块,然后根据 x, z 设置y坐标值和颜色(跟y有关),
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; |
为了增加随机性, 对x,z 的系数做随机:
_seedX = Random.value * 100f; _seedZ = Random.value * 100f; |
比如使用噪声生成 类似我的世界的地图等
代码相对简单,直接在Awake 函数中执行生成了 地图!
改变 尺寸 (宽度和深度)
改变 最大高度
如果不启用柏林噪声,而是使用随机的效果:
平整度:
还有是否添加碰撞体:
_relief 跌宕起伏,决定了 采样的间隔大小。值越大跨度越小。
地图大小,就是控制父对象的scale
// RandomMapMaker.cs using UnityEngine; using System.Collections; using System.Collections.Generic; public class RandomMapMaker : MonoBehaviour { private float _seedX, _seedZ; [SerializeField] private float _width = 50; [SerializeField] private float _depth = 50; [SerializeField] private bool _needToCollider = false; [SerializeField] private float _maxHeight = 10; [SerializeField] private bool _isPerlinNoiseMap = true; [SerializeField] private float _relief = 15f; [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); foreach (Transform child in transform) { SetY (child.gameObject); } } 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); } 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; } }
参考:
百度百科: http://baike.baidu.com/item/%E6%9F%8F%E6%9E%97%E5%99%AA%E5%A3%B0
http://postd.cc/understanding-perlin-noise/
http://evilonedeath.blog.fc2.com/blog-entry-127.html
http://befool.co.jp/blog/ayumegu/unity-study-Noise/
http://kan-kikuchi.hatenablog.com/entry/PerlinNoise