読者です 読者をやめる 読者になる 読者になる

(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

パーリンノイズでマイクラみたいなマップの自動生成【Unity】

Unity

このエントリーをはてなブックマークに追加

この記事でのバージョン
Unity 5.3.1f1 Personal


はじめに

Mathfについての記事を書いていた所、

Mathf.PerlinNoiseになる見慣れない関数を発見しました。


どうやらこれを乱数を発生させる関数らしく、自動マップ生成にも使えるそうです。



面白そうなので簡単に使ってみました!


PerlinNoise

そもそもPerlinNoiseとは、なんぞやという事ですが。

コンピュータグラフィックスのリアリティを増すために使われるテクスチャ作成技法。擬似乱数的な見た目であるが、同時に細部のスケール感が一定である。このため制御が容易であり、各種スケールのパーリンノイズを数式に入力することで多彩なテクスチャを表現できる。

パーリンノイズ - Wikipedia


どうやら元々はノイズ用(?)のテクスチャを作るのが目的らしく、

これを使うと濃淡が滑らかで自然なノイズテクスチャができるようです。


詳細はは以下の記事をどうぞ!





マップ生成

まず、xとzが共に50の広さ、高さは0~10の範囲で完全ランダム

でマップを自動生成した場合以下のような感じになります。

なお、敷き詰めてるCubeのスケールは1×1×1で、高さによって段階的に色を変えています。


f:id:kan_kikuchi:20160316135035p:plain


ただランダムにキューブがあるだけでマップには見えませんね……。


では同様の条件でパーリンノイズ を使ってみると以下のような感じになります。


f:id:kan_kikuchi:20160316135312p:plain


だいぶマップっぽくなりましたね!


RandomMapMaker

実際に使用したコード、RandomMapMakerは以下の通りです。



色々書いてますが、パーリンノイズはを使っているのは以下の所です。

float xSample = (cube.transform.localPosition.x + _seedX) / _relief;
float zSample = (cube.transform.localPosition.z + _seedZ) / _relief;

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


Mathf.PerlinNoiseは入力に応じて0~1の値を返すので、

それに最大の高さをかけてy座標を決定しています。


なお、Mathf.PerlinNoiseは入力から出力が一意に決まるので、

_seedXと_seedZを乱数にする事で同じマップが生成される事を避けています。

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


逆に言えば_seedXと_seedZが同じならば何度でも同じマップを生成できるということにもなります。


使い方はRandomMapMakerをてきとうなオブジェクトに付けて、実行するだけです。

Awake関数内でランダムでマップが生成されます。

また、マップの形は実行される度に変わります。


f:id:kan_kikuchi:20160317132835p:plain f:id:kan_kikuchi:20160317132841p:plain


さらに、生成されるマップの情報はインスペクターから設定するようにしています。


広さ(Width, Depth)

Widthでx方向に並べるcubeの個数、

Depthでz方向に並べるcubeの個数を決めています。


f:id:kan_kikuchi:20160317133400j:plain


なおy方向には常に1個のcubeしか置いていません。


最大の高さ

Max Heightで最大の高さを決めています。


f:id:kan_kikuchi:20160321072847g:plain


なんか楽しい(:3っ)∋〜


パーリンノイズを使う

Is Perlin Noise Mapでパーリンノイズを使うかを決めています。

チェックを外すと最初のランダムに高さを設定したマップ(?)ができます。


f:id:kan_kikuchi:20160321072503g:plain


起伏の激しさ

Reliefで起伏の激しさを決めています。


f:id:kan_kikuchi:20160321072945g:plain


これも楽しい(:3っ)∋〜


滑らかさ

Is Smoothnessで滑らかにするかを決めています。


f:id:kan_kikuchi:20160321073039g:plain


滑らかな感じだとマイクラっぽくないので

yの座標の小数点を四捨五入してそれっぽくしてみました



------追記(2016.04.08)

コライダー

Need To Colliderでコライダーを使うかを決めています。

チェックを外すと全ブロックのコライダーが無くなります。


f:id:kan_kikuchi:20160408133300j:plain


マップの大きさ

Map Sizeでマップの大きさを決めています。


f:id:kan_kikuchi:20160408133907g:plain



------追記終わり(2016.04.08)

おわりに

ただそれっぽい地形を作っただけですが、びっくりするほど簡単にできました!

パーリンノイズ恐るべしべし(:3っ)∋〜

参考