シンプルなタワーディフェンスゲームを作る part5
こちらのようなシンプルなタワーディフェンスゲームを作っています。本記事では「自軍拠点」に向かってくる「敵ユニット」のうち、射程内かつ「自軍拠点」に最も近い「敵ユニット」を選択して攻撃する砲台を作ります。またどの「敵ユニット」を対象としているか分かるよう砲台を常に「敵ユニット」に向け続ける動きも付けます。
砲台タワーの外観を作る
初めに砲台タワーの外観を作ります。砲台は地面に接地する土台部分と、「敵ユニット」を追いかける砲台部分の二つの部品で作ります。
土台用に ビューポートで「モデリングモード」→「作成」→「Cylinder」で円柱を作成します。大きさはRadiusを50、Heightを50としました。
次に砲台部分を作ります。「モデリングモード」→「作成」→「Cylinder」でRadius30、Height50の円柱を2つ作成し、片方の円柱を移動・回転して下図のような位置関係にします。
この2つの円柱は1つのオブジェクトとして扱えるようにします。Shiftを押しながら2つの円柱を選択した状態で「モデリングモード」→「メッシュ」→「Union」を選択し「承諾」を押下することで円柱をマージすることができます。
2つの円柱をマージした砲台オブジェクトの原点を回転中心にしたいので、原点を調整します。
「モデリングモード」→「XForm」→「Edit Povot」を選択します。原点を移動できるようになるので下図のような位置(縦になっている円柱の底面中央)に移動させ「承諾」ボタンを押下します。
「tower」フォルダを作成します。ここに砲台タワー関係の部品を入れていきます。先ほど作成した2つのオブジェクト(「土台」広めの円柱、「砲台」細めの円柱の組み合わせ)を「tower」フォルダに移動し、「土台」を「SM_tower_base」、「砲台」を「SM_tower_turret」という名称にします。
※「モデリングモード」で作成したオブジェクトは「level」を開いているフォルダの中の「_GENERATED/ユーザー名」のフォルダに格納されています。(part1も参照ください)
砲台タワーのブループリントを作ります。
「tower」フォルダ内で右クリック→「ブループリントクラス」を選択し、今回は「Pawn」を継承し、「BP_tower」という名前にします。
「BP_tower」を開きます。先ほど作成した「SM_tower_base」「SM_tower_turret」をビューポートにドラッグアンドドロップします。左上の「コンポーネント」パネルの「追加」から「Arrow」を検索して追加します。「Arrow」を「turret_direction」という名前に変更します。
「turret_direction」を「SM_tower_base」の子、「SM_tower_turret」を「turret_direction」の子にします。
左上の「コンポーネント」パネル上で子にしたいオブジェクトを、親にしたいオブジェクトの上にドラッグアンドドロップすることで、親子関係を設定することができます。
砲台タワーの色を設定します。part2 と同じ要領でマテリアル「M_tower」を作成し、ベースカラーに緑色を設定、「SM_tower_base」と「SM_tower_turret」に作成したマテリアルを割り当てます。
攻撃対象とする「敵ユニット」を取得する
「BP_tower」のイベントグラフを開きます。距離の判定に使用するため「自軍拠点」のオブジェクトを取得しておきます。「Event BeginPlay」から下図のようにノードを接続し、「headquater」という変数を作ります。
Float型変数「attack_range」「nearest_distance」を作り、デフォルト値を1000、999999.0と定義します。
「Event tick」ノードから下図のようにノードを繋げていきます。
※ オブジェクト参照にするため「BP_enemy」型の「target_enemy」変数は右クリック→「変数へ昇格」で作成します。
この処理より、レベル内すべての「敵ユニット」を取得し、一つずつ「射程範囲内かどうか」「自軍拠点までの距離が近いかどうか」を判定し、射程範囲内かつ自軍拠点への距離が最も近い「敵ユニット」を選択します。
上記の「攻撃対象を選択する処理」の前にいくつかの変数を初期化する必要があります。
下図のように、「target_enemy」と「nearest_distance」を初期化する処理を「攻撃対象を選択する処理」の前に追加します。
「敵ユニット」に砲台を向ける動きを作る
「攻撃対象を選択する処理」の続きとして、「For each loop」の「Completed」ピン以降に「敵ユニットに砲台を向ける処理」を書いていきます。
まず「target_enemy」が有効なオブジェクトとなっているか判定します。「target_enemy」は初めにNoneとして初期化しているので「攻撃対象を選択する処理」でオブジェクトが選択されていなければNoneのままです(射程内に敵ユニットがいない場合等)。
「target_enemy」が有効なオブジェクトの場合の処理を作ります。
下図のようなノードを組み合わせることで、常に「target_enemy」の向きに「turret_direction」が向くような動きにすることが出来ます。
「敵ユニットに砲台を向ける処理」の完成図。
「敵ユニット」を攻撃する
「敵ユニット」に攻撃してダメージを与える処理を作ります。設定した頻度で攻撃するような仕様にしたいので、攻撃頻度を「fire_rate」として定義します。(ここではfire_rate=0.5秒)としました。
前回攻撃した後からの経過時間を数える変数「timer」を定義します。「timer」には「Event tick」の「Delta Seconds」を加算していき、「fire_rate」を超えたタイミングで攻撃し「timer」を初期化します。
攻撃はpart3と同様に「Apply Damage」イベントを「target_enemy」に通知することで行います。
与えるダメージは「attack_power」という変数で定義します。今回はデフォルト値を10に設定します。
「BP_enemy」を開きます。下図のように、「Event AnyDamage」を追加し、受けたダメージ量を表示するようにします。
これでゲームを実行すると、冒頭の動画のようにタワーの砲台が敵ユニットに常に向き続け、設定した頻度で攻撃し続ける砲台タワーの振る舞いを確認できます。
おまけ:全体像
今回作った「BP_tower」の攻撃処理の全体像を下図に示します。
コメント