Unity 2D Roguelike 公式チュートリアル Game Manager編を使った学習(5/14)

本稿、または本シリーズは私自身が理解できるように、Unity初心者の方が読んでも理解できるような説明を心がけています。とはいえ、あくまでも個人の記録なので、ノークレームでお願いします。ご理解の上、読んで頂きますようお願いします。

学習のコツ: 公式チュートリアルの動画を観れば大体は手順は分かります。慣れている人は本稿をすっ飛ばしても良いでしょう。ただし、本稿では公式チュートリアルではカバーしていない「なぜ、そうするのか」という意図も解説していたりします。初学者の方の参考になれば幸いです。

Unity 2D Roguelike 公式チュートリアルを学習シリーズ PART5(全14回) Game Manager編

本稿ではUnity公式チュートリアル 2D Roguelikeの第4回を日本語で学ぶ回になっています。

ゲーム全体をまるっと管理してくれるGameManagerを作る

今回もゴリっとスクリプトを書いていきます。GameManagerというやつを作ります。前回と同様、基本は上の動画を観ながら手を進めて、分からないところがあれば本稿を参考にしてください。

※筆者もひよっこなので、理解に乏しい箇所がありますが暖かい目で見守ってください

GameManager

GameManagerはゲーム全体を管理してくれます。そして、本稿では前回書いたBoardManagerと組み合わせて、ゲーム内で動かせるようにします。

boardScript

前回作ったBoardManagerクラスからboardScript変数を作ります。

int型の変数 level

private int level = 3;

このlevelはステージの階層を表しています。3にした理由は前回作ったBoardManagerの設定上、レベル3から敵がポップするためです。

Awake

    void Awake()
    {
        boardScript = GetComponent<BoardManager>();
        InitGame();
    }

AwakeはStart関数よりも早く呼ばれます。その中身では先ほど作った、boardScriptにBoardManagerコンポーネント(C#Script)を入れてあげています。何かしらコンポーネントを扱ったコードを書く場合、必ず読み込ませる必要はあります。それはスクリプトも例外ではありません。

Tips: もし、この時点でUnityエディタのヒエラルキー上のGameManagerにAssets/ScriptsフォルダのGameManagerとBoardManagerスクリプトをコンポーネントに加えていない場合、ドラッグアンドドロップ、またはAddComponentで追加してください。

Awake内のInitGame()はこれから作る関数です。

InitGame()

    private void InitGame()
    {
        boardScript.SetupScene(level);
    }

InitGame()内では前回作った、BoardManagerのSetupSceneを呼んでいます。また、先ほど作ったint型の変数「level」を渡していますね。

前回作ったBoardManagerのSetupSceneを再確認しましょう。

    public void SetupScene(int level)
    {
        BoardSetup();
        InitialiseList();
        LayoutObjectAtRandom(wallTiles, wallCount.minimum, wallCount.maximum);
        LayoutObjectAtRandom(foodTiles, foodCount.minimum, foodCount.maximum);
        int enemyCount = (int)Mathf.Log(level, 2f);
        LayoutObjectAtRandom(enemyTiles, enemyCount, enemyCount);
        Instantiate(exit, new Vector3(columns - 1, rows - 1, 0f), Quaternion.identity);
    }

引数に(int level)とありますね。ここで渡されたlevel変数は「int enemyCount」で使われています。ちなみにこのenemyCountの計算に使われているMathfやLogというものはUnityではよく使う計算です。

MathfはFloat型の計算を返してくれる便利なものです。Logは対数を出してくれます。数学は専門ではないのでここでは省略しますが、何かしら解説は別の記事でする可能性はあります。

UnityエディタでBoardManagerへPrefabをセットする

Unityエディタに戻って、BoardManagerにPrefabをセットしていきます。前回、いろいろな変数や配列を用意しましたね。その中にPrefabを入れることできちんと動作します。公式チュートリアルの動画を観た方が早いのでここでは細かな手順は省略します。

動画の途中でも説明はありますが、インスペクタウィンドウの右上の鍵マークをクリックすることで、他のオブジェクトやPrefabをクリックしてもインスペクタが固定されます。解除したい時はもう一度クリックしてアンロックしましょう。

Singleton シングルトン

このゲームに一つしかないものとして宣言します。まずはnullにしておいて、ゲーム開始時にGameManagerのAwakeで自身をGameManagerのinstanceであると設定します。

public static GameManager instance = null;
void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else if (instance != null)
        {
            Destroy(gameObject);
        }
        DontDestroyOnLoad(gameObject);
        boardScript = GetComponent<BoardManager>();
        InitGame();
    }

instanceはこのゲームに2つ必要ないので、このような処理をします。Don'tDestroyOnLoadは次のレベルに入った時にロードされますが、その際にこのinstanceを保持したままにしたいので入れています。

 GamaManagerをPrefab化

GameManagerをPrefab化します。

Loader

最後にLoaderというスクリプトを新たに作成しましょう。Assets/Scripts内に作ります。

LoaderはGameManagerが生成されているかどうか確認するためのシンプルなスクリプトです。

public class Loader : MonoBehaviour
{
    public GameManager gameManager;

    void Awake()
    {
        if (GameManager.instance == null)
        {
            Instantiate(gameManager);
        }
    }
}

GameManager型の変数gameManagerを準備。Awake内で「もし、GameManager.instance(シングルトン)が空だったらgameManager Prefabを生成します」といったものです。

保存し、Unityエディタに戻ったらMain CameraにLoaderをアタッチしてくただい。アタッチしたら、MainCameraのインスペクタ→LaderコンポーネントにGameManagerのPrefabを入れます。そして、ヒエラルキー上のGameManagerは削除します。

Main CameraにLoaderをアタッチし、GameManagerをセット

まとめ

本稿ではGameManagerスクリプトの処理を書いてきました。BoardManagerと比べるとコードの量も少なく、理解しやすかったのではないでしょうか。次回もこのくらいのボリュームでお届けできれば幸いです。


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