![見出し画像](https://assets.st-note.com/production/uploads/images/88680021/rectangle_large_type_2_61513cdb905a3ef3d38d82bb70956a18.png?width=1200)
[unity][C#Script] パーリンノイズを利用して地形を生成する。(Terrain版)
Unity の標準機能のみをつかって、地形を自動生成してみます。前回はメッシュでの生成でしたが、今回はテレインです。
Unity標準のエディット機能で、地形を微調整したりとか、テクスチャをペイントしたりとかが自由にできるので、よりゲームに使いやすくなるのではないでしょうか。
![](https://assets.st-note.com/img/1642207582302-tEVJ9uQsaF.png?width=1200)
![](https://assets.st-note.com/img/1642207652637-krzRnQA8Nc.png?width=1200)
なお、今回の記事はパーリンノイズを使っています。技術的な詳細は前回の地形の生成と同じになりますので、そちらをご覧ください。
また、木やテレインのテクスチャはUnityの標準アセットを使用しております。とりあえず見栄えを調整してみたいときなどに使用してください。
ゲームっぽい見栄えの木としては、有料アセットのAZURE Natureのものが使い勝手がよいと思います。
1. Terrainの設置
ヒエラルキー → 3Dオブジェクト → Terrain(地形) で、シーンにテレインを作成します。
2. スクリプトの追加
テレインを選択し、インスペクターから
コンポーネントの追加 → 新しいスクリプト で、スクリプトを追加します。スクリプトの名前は「AutoGenerateTerrain」とします。
コードは以下をコピーします。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AutoGenerateTerrain : MonoBehaviour
{
//public GameObject contextTerrain;
public float scale = 1.0f;
public float freq = 0.01f;
public float flatWidth = 0.1f;
public float roadfreq = 0.005f;
public float roadWidth = 0.05f;
private float perlinHeight;
private float road1Start;
private float road1End;
private float roafFlug;
private float road2Start;
private float road2End;
[ContextMenu("生成")]
private void makeGround()
{
TerrainData genTerrain = GetComponent<Terrain>().terrainData;
var heights = new float[genTerrain.heightmapResolution, genTerrain.heightmapResolution];
for (int x = 0; x < genTerrain.heightmapResolution; x++)
{
for (int y = 0; y < genTerrain.heightmapResolution; y++)
{
float r1height = Mathf.PerlinNoise(x * roadfreq, y * roadfreq)*0.2f+0.3f;
float r2height = Mathf.PerlinNoise(x * roadfreq + 500, y * roadfreq +500)*0.2f+0.5f;
road1Start = r1height - flatWidth / 2;
road1End = r1height + flatWidth / 2;
road2Start = r2height - flatWidth / 2;
road2End = r2height + flatWidth / 2;
// Terrainの高さを算出
// パーリンノイズから高さのベースを算出
perlinHeight = Mathf.PerlinNoise(x * freq, y * freq);
heights[x, y] = convSlope1(perlinHeight);
roafFlug = Mathf.PerlinNoise(x * roadfreq, y * roadfreq);
}
}
genTerrain.SetHeights(0, 0, heights);
}
private float convSlope1( float slope )
{
// 高い方の平地を作る。
if (slope > road2Start)
{
//slope = slope - flatWidth;
if (slope < road2End)
{
slope = road2Start;
} else
{
slope -= flatWidth;
}
}
if (slope > road1Start)
{
//slope = slope - flatWidth;
if (slope < road1End)
{
slope = road1Start;
} else
{
slope -= flatWidth;
}
}
return slope;
}
}
3. 地形の自動生成
インスペクターのスクリプト名称あたりを右クリックし、メニューから「生成」を選択します。
![](https://assets.st-note.com/img/1642208605906-yM1oW5L4iX.png)
![](https://assets.st-note.com/img/1642208692357-dkZjO1bOib.png?width=1200)
これに地形テクスチャを塗り、木を植え、草を生やすことで、見栄えのよい地形が作れると思います。
また、地形のアップダウンなどの調整も、テレインが持っている機能を使って編集することが可能です。
地形編集について、どんなことができるかは、以下の有料アセットをつかって地形をつくってみたときのノートを参考にしてみてください。テレインっていろいろなことができるんだな、便利かも? と思っていただけるとうれしいです。
特にPathPainterII はイチオシです。標準ツールはちょっと(かなり)使いにくいので。
4.技術的な補足
スクリプトはパーリンノイズで各ポイントの高さを決め、それをTerrainData の SetHeights でテレインに適用しています。
その際、スロープの一部をフラットにつぶす処理をいれることで、斜面の中腹に道のような平面ができます。
パーリンノイズの特性上、この道はいろんなところに繋がりますが、それがゲーム的なルールにあいそうではないかなと思います。
皆さんにも、ぜひともスクリプトをいろいろといじっていただいて、その結果面白い作品を作るきっかけになってもらえれば、このうえない喜びです。
ではまた。ゲーム制作者魂がともにあらんことを。(k1t)