見出し画像

[unity][C#Script] パーリンノイズを利用して地形を生成する。(Terrain版)

 Unity の標準機能のみをつかって、地形を自動生成してみます。前回はメッシュでの生成でしたが、今回はテレインです。
 Unity標準のエディット機能で、地形を微調整したりとか、テクスチャをペイントしたりとかが自由にできるので、よりゲームに使いやすくなるのではないでしょうか。

標準アセットの草原と岩肌をペイントし、木を植えたところです。
視点をFPS風にしてみたところです。

なお、今回の記事はパーリンノイズを使っています。技術的な詳細は前回の地形の生成と同じになりますので、そちらをご覧ください。

 また、木やテレインのテクスチャは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. 地形の自動生成

インスペクターのスクリプト名称あたりを右クリックし、メニューから「生成」を選択します。

「生成」を選ぶ
前回と同じような地形が生成されました

 これに地形テクスチャを塗り、木を植え、草を生やすことで、見栄えのよい地形が作れると思います。
 また、地形のアップダウンなどの調整も、テレインが持っている機能を使って編集することが可能です。
 地形編集について、どんなことができるかは、以下の有料アセットをつかって地形をつくってみたときのノートを参考にしてみてください。テレインっていろいろなことができるんだな、便利かも? と思っていただけるとうれしいです。

特にPathPainterII はイチオシです。標準ツールはちょっと(かなり)使いにくいので。

4.技術的な補足

 スクリプトはパーリンノイズで各ポイントの高さを決め、それをTerrainData の SetHeights でテレインに適用しています。
 その際、スロープの一部をフラットにつぶす処理をいれることで、斜面の中腹に道のような平面ができます。
 パーリンノイズの特性上、この道はいろんなところに繋がりますが、それがゲーム的なルールにあいそうではないかなと思います。

 皆さんにも、ぜひともスクリプトをいろいろといじっていただいて、その結果面白い作品を作るきっかけになってもらえれば、このうえない喜びです。

 ではまた。ゲーム制作者魂がともにあらんことを。(k1t)


ex.参考になりそうな記事

この記事が参加している募集

ゲームの作り方

この記事が気に入ったらサポートをしてみませんか?