見出し画像

Unityやってみる23:スクリプトひとつで迷宮を生成してみました

 こんにちは。Unity素人おじさんです。ただしプログラミング歴は結構長いです。

 前回は、新規作成したプロジェクトに、「地面を発生させて、そこにカラフルなボールを降らせてみる」というデモを、報告させていただきましたね。

 今回はもうちょっとだけ実用的な、デモをお届けしたいと思います。それは何かというと、「スクリプトひとつで迷宮を生成する」デモです。

 それではまいりましょう。


  まず今回も、Unity Hubから「新しいプロジェクト」を作成します。使うテンプレートは、「3D コア」ですね。

 プロジェクト新規作成後の状態です。メインカメラとライトだけが設置された状態ですね。

 今日もその状態で、Main Cameraにスクリプトをアタッチします。名前は前回と同じ、「TestScript」にしておきます。


 TestScriptを開いて、次のコードを貼り付けましょう。コードの説明は後で簡単に行います。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour
{

    float num = 10f;

    string[] maze = new string[] {
        "■■■■■■■■■■",
        "■□■□□□■□□■",
        "■□■■■□■■□■",
        "■□□□□□□□□■",
        "■■■■□□■■■■",
        "■□□□□□□□□■",
        "■□■□■■■□■■",
        "■■■□■□□□□■",
        "■□□□□□■■□■",
        "■■■■■■■■■■",

    };

    private void make_ground(float num)
    {
        //Planeオブジェクトを追加して地面にする
        GameObject Plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
        Plane.transform.localScale = new Vector3(2f, 2f, 2f);
    }

    private void move_camera()
    {
        //カメラの移動と回転
        transform.position = new Vector3(0, 10, -10);
        Quaternion newRotation = Quaternion.Euler(50f, 0f, 0f);
        transform.rotation = newRotation;
    }

    void SetBlock(float num, float x, float z, Color col)
    {
        GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);

        obj.transform.position = new Vector3((float)x * 2f - num + 1f, 0.5f, (float)z * 2f - num + 1f);

        obj.GetComponent<Renderer>().material.color = col;

        obj.transform.localScale = new Vector3(2f, 4f, 2f);

        //        Rigidbody rb = obj.AddComponent<Rigidbody>();

    }

    void Start()
    {
        make_ground(num);
        move_camera();

        Color col = new Color(0.3f, 0.3f, 0.3f);

        for (int i = 0; i < num; i++)
        {
            for (int j = 0; j < num; j++)
            {
                if (maze[i].Substring(j, 1) == "■")
                {
                    SetBlock(num, i, j, col);
                }
            }
        }
    }
}

 コピペしたら、セーブして、実行してみましょう。やりました、迷宮が出来ましたー! 簡単ですね。

 ソースコードを簡単に解説します。

 まず最初に、「num」という変数に10を設定しています。これは迷宮の、縦横のブロックの個数を表しています。

    float num = 10f;

 mazeという配列変数で、壁のありなしを設定します。「■」が壁あり。「□」が壁なしを表しています。ここをいじると、迷路の作りが変更できますよ。

    string[] maze = new string[] {
        "■■■■■■■■■■",
        "■□■□□□■□□■",
        "■□■■■□■■□■",
        "■□□□□□□□□■",
        "■■■■□□■■■■",
        "■□□□□□□□□■",
        "■□■□■■■□■■",
        "■■■□■□□□□■",
        "■□□□□□■■□■",
        "■■■■■■■■■■",

    };

 make_ground関数は、呼び出されると白い地面を生成します。その大きさは、縦横高さを、すべて2倍にしています。nのサイズに合わせて、自動で大きさを変更するように、改造してみてもいいですね。

    private void make_ground(float num)
    {
        //Planeオブジェクトを追加して地面にする
        GameObject Plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
        Plane.transform.localScale = new Vector3(2f, 2f, 2f);
    }

 カメラの位置と角度を、スクリプト内で調整します。前回とか今回のように、スクリプト内ですべてのオブジェクトを生成する方法だと、カメラの位置を調整するのがすごく難しいですね。工夫が必要な部分です。

    private void move_camera()
    {
        //カメラの移動と回転
        transform.position = new Vector3(0, 10, -10);
        Quaternion newRotation = Quaternion.Euler(50f, 0f, 0f);
        transform.rotation = newRotation;
    }

 ブロックを配置するための関数です。引数で、縦横のサイズと、配置する座標(x,z)、ブロックの色を、与えることが出来ます。ブロックのサイズは、縦横のサイズを2倍に、高さを4倍にしています。

    void SetBlock(float num, float x, float z, Color col)
    {
        GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);

        obj.transform.position = new Vector3((float)x * 2f - num + 1f, 0.5f, (float)z * 2f - num + 1f);

        obj.GetComponent<Renderer>().material.color = col;

        obj.transform.localScale = new Vector3(2f, 4f, 2f);

        //        Rigidbody rb = obj.AddComponent<Rigidbody>();

    }

 最後に、メインとなるstart関数です。make_ground、move_cameraで、舞台設定をざっと終え、ブロックの色colを決めた後、ループ文forを使ってx座標、z座標のブロック有り無しをチェックし、有りだったらブロック設置関数をコール、ですね。

    void Start()
    {
        make_ground(num);
        move_camera();

        Color col = new Color(0.3f, 0.3f, 0.3f);

        for (int i = 0; i < num; i++)
        {
            for (int j = 0; j < num; j++)
            {
                if (maze[i].Substring(j, 1) == "■")
                {
                    SetBlock(num, i, j, col);
                }
            }
        }

 オブジェクトの、スクリプトからの動的な生成の方法と、C#の言語リファレンスがわかってしまえば、スクリプトだけで、こういうステージを作成可能です。

 しかしこうやって生成したステージを、さらにスクリプトだけでゲームとして利用できるのか、というのはまだ試せてないので、次回検討したいと思っています。可能なら、スクリプトだけでゲームを完成させることができると楽しいのですけどどうなるでしょうか! ご期待ください。

次回はこちら:

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