敵の生成処理の作り方 ウェーブの作成とレベルデザインまで

Unity タワーディフェンスゲームの作り方


Unityの本格ゲーム制作講座はこちら
【30日間の全額返金保証付き】

前回(第5回)では、経路に沿って実際に敵オブジェクトが移動する仕組みなどを作りました。

前回の記事↓

【敵の移動処理の作成2】目的地の設定とベクトルを用いた経路設計
前回(第4回)では、敵の経路を作成しました。 前回の記事↓ 第5回である今回は、その経路に沿って実際に敵オブジェクトが移動する仕組みなどを作っていきます。 どんどんタワーディフェンスらしくなってきますね。 敵(Enemy)スクリ...

今回は敵オブジェクトの作成を制御する仕組みを作っていきます。

Waveの概念も入ってきてあなたのレベルデザインの見せ所になります。では、作っていきましょう。

タワーディフェンスゲームでは一連の敵が出てくる流れ1セットをウェーブと呼びます。そして、決められた回数のウェーブを全て耐え、HPが0にならなければ勝ちです。

EnemyManagerの作成

敵オブジェクトを複数出現(生成)させていくにあたり、その生成タイミング等を管理するオブジェクト(EnemyManager)を作ります。
Hierarchyビューに、新規オブジェクト(CTRL+SHIFT+N)を作成し、新規ScriptもAddComponentします。

  • 名前:EnemyManager
  • スクリプト名:EnemyManager

では、EnemyManagerスクリプトを作成していきます。 このEnemyManagerに必要な要件としては

  • 今が第何waveか管理 (wave)
  • waveがスタートしてからの経過時間を管理 (time)
  • 生成する敵(Enemy)が指定できる
  • 生成する時間(Time)が指定できる
  • Enemyが通る経路(Route)が指定できる

この辺りになります。

この、Time,Enemy,Route をワンセットで管理するEnemyPatternクラスと、1ウェーブは複数の敵の出現パターンで構成されるので、EnemyPatternをListで管理するWaveクラスをEnemyManagerクラスのに書いておきます。

[Serializable]という、あまり見慣れないAttribute(アトリビュート)がありますが、これを書くことでInspectorに表示され、中身をUnityEditorで設定することが出来るようになる。

と考えておくとよいです。

興味がある方は試しにこの[Serializable]を外してみてください。
Inspectorで表示されなくなります。

次に、実際に敵を生成する関数を作ります。

 

EnemyManagerスクリプトに以下のCreateEnemy関数を追加します。

この関数の中でやっていることはまず

foreachで現在のウェーブ(wave)の敵パターンを全部patternに入れつつ回します。

foreachの中のif文では、メンバ変数 time の秒数から、生成されてなければいけない敵かどうかを判定しています。

生成の必要がある場合は、Instantiate でpatternにセットされているEnemyのprefabを生成(複製)した後、patternにセットされているRoute(経路)をセットして、生成したEnemyオブジェクトが経路に沿って移動する準備をしています。

なおInstantiate で生成(複製)する際に生成位置(Vector3)と回転(Quaternion)を渡すことが出来るのですが、生成位置には new Vector3(-1000,-1000) という、画面に絶対映らない凄い外を指定しています。

これは生成した敵(Enemy)が画面中央に一瞬表示される事があったため予防策で指定しています。

回転(Quaternion)は特に指定が無いので Quaternion.identity という、無回転を意味するQuaternionを渡しています。

そして最後に、ListRemoveAllメソッドを使って既に生成したEnemyをもう一度作らないようにListから削除しています。

ただし、このCreateEnemy関数ですが、まだ誰からも呼ばれていません。
これでは確認ができないので、Update関数にテスト用の処理を書きましょう。

なおあくまでもテスト用なので、この次回以降の講座のどこかで削除します。

waveは取り合えず0固定で、経過時間はTime.deltaTime(前回フレームからの経過時間)を足しこんでいきます。

以下が今回作ったEnemyManagerスクリプトのプログラム全体になります。

※void Start(){ } は使用しないので削除してありますが、残っていても構いません。

忘れずにスクリプトの保存をし、UnityEditorに戻ります。

ちなみにUnityEditorで再生をしてみても何も動きません。
それはそうです、まだWaveの中身を用意していないですからね。

では、Waveの中身を作っていきます。

Waveの作成

とりあえず、Waveは1つだけ作りましょう。 Size を 1 に変更します。

すると今度はWaveの中身、PatternsのSize が0です。
これが、第1ウェーブで何匹の敵を出現させるか。という意味になります。

とりあえず、これも 1 にしておいてください。

Patternsの中身は 先ほど用意した EnemyPattern クラスなので、EnemyPatternクラスのメンバ変数である、time,enemy,routeがさらにInspectorから指定できるようになっています。

適当なEnemyと、Routeをドラッグアンドドロップでセットします。(Timeは0のままでよいです)

ここで、注意なのですが、EnemyはAssets/Prefabs の中に作ってあるprefabを入れてください(HierarchyビューのEnemy(青字)からドラッグアンドロップしないように)。

これで、とりあえず指定した敵1体が0秒(開始と同時)に指定した経路で動き出すようになっているはずなんですが、Enemyを作った時にHierarchyに作ったEnemy,Enemy (1),Enemy (2) が最初からあると混同してしまって分かりづらいですね。

その3つは今のうちに選択してDELETEキーで消してしまいましょう。 では、再生ボタンを押してみてください。 敵が生成されました!

敵パターン増産

このままでは1体しか敵が出てこない事になってしまいます。

先ほど作った Patterns の Element 0 を右クリックして、Duplicate Array Elementを選択することで、複製できます(この場合だとElement 1が作られます)

この要領で複製を繰り返して、Patterns の Size を 5 まで増やし、1秒間隔で出現するように、Timeが1ずつ増えていくように修正しましょう。

1秒間隔で、5体のEnemyが列になって動きました! もちろん、同じEnemyのprefabだけじゃなくても構いませんし、Timeに小数点を入れても構いません。経路(Route)も好きに変更してみて、自分だけのウェーブを作ってみてください。

コツは、ちょこちょこと再生をして、結果を確認する事です。

<例>

おさらいと次回予告

今回は敵を管理するEnemyManagerを作成し、Inspectorで敵の出現パターンを指定してウェーブが作れるようになりました。

次回は、この敵を倒す弓矢を作っていきます。

次回の記事↓

敵当たり判定とコルーチンを用いた弓矢の生成&射出処理の作成
前回(第6回)では、ウェーブを作って、敵オブジェクトの出現パターンを制御する仕組みを用意しました。 前回の記事↓ 見た目だけは大分ゲームらしくなってきましたが、まだ敵を倒すことが出来ません。 今回は敵の当たり判定(Collider2...

コメント

  1. bananan より:

    いつも楽しく進めさせて頂いております

    毎回、目から鱗が落ちる思いで体験させてもらっています

    ところで、今回の「敵の生成処理の作り方 ウェーブの作成とレベルデザインまで」ですが
    「Waveの作成」項目のEnemyManagerの要素0のEnemy欄に、Prefabsの敵を入れる箇所がブログの通りになりませんでした
    試行錯誤したところ、以前のブログ「敵オブジェクトの作成・パラメータ設定・敵処理のプロトタイプの作成」
    のPrefabsを作る際に、子オブジェクトである「sprite」を入れると上手くEnemy欄に収まりました

    Unity初学者なので見当違いことを言っているかもしれませんが
    もしかしたら記載間違いかもしれないので、念のためご報告いたします

    • ばこ より:

      コメントありがとうございます。
      Unity入門の森のゲームの作り方講座を楽しんでいただけてるようでうれしいです^^

      さて、プレハブですが、そもそもEnemyオブジェクト制作の過程でspriteは子オブジェクトになっています。
      ヒエラルキーでspriteを子オブジェクトとしたEnemyをプレハブにしているので。
      講座をそのまま進めていただければちゃんとEnemy欄に収まるはず。

      お気づきになられたこと教えていただきありがとうございます。

      • askr より:

        >管理人さん
        私もいつもこのサイトで勉強をさせていただいております。
        とてもわかりやすく感謝しております。

        >banananさん
        私もUnity初学者で同様の問題となりEnemy欄にPrefabsを設定することができませんでした。いろいろと試した結果原因が解明できたため共有いたします。

        「敵オブジェクトの作成・パラメータ設定・敵処理のプロトタイプの作成」の記事にて、Enemyを作成した際にEnemyスクリプトを親オブジェクトではなく子オブジェクトのSprite側に設定しているため、設定することができませんでした。
        (spriteをPrefabs化した際に設定できたのはこのためと思われます。)

        記事を読み返すとEnemyスクリプトが親オブジェクトに設定されておりましたので、作成した際の誤りだと思われます。

        私も見当違いなことでしたらすみません。
        では。

        • Unity入門の森 より:

          >askrさん
          コメントありがとうございます!
          お役に立てているようで幸いです^^

          EnemyオブジェクトにEnemyスクリプトが割り当てるところを間違えるとその状態に至るとのことですね。
          作成時にありがちな誤りとして追記しておきます。
          情報提供ありがとうございました!

タイトルとURLをコピーしました