春日部つむぎ no ゲーム作ってみよう!【UE5/UE4】 - 向かって来る敵【UE5/UE4】


https://youtu.be/5GykRRd1Z4M

00:00 オープニング
00:51 1.Enemy作成
00:53  1-1.EnemyBlueprints作成
     ※親クラスの変更
01:40  1-2.ビューポート
02:58 2.Enemyイベントグラフ
03:08  2-1.プレイヤーに向かって来る処理
04:29  2-2.Enemyの移動範囲を設定
05:17  2-3.敵がプレイヤーに接触すると爆発する
07:04  2-4.プレイヤーの特定
08:18  2-5.プレイヤーにダメージを与える処理
09:14  2-6.プレイヤーからダメージを受ける処理
     ※ブループリントインターフェースの作り方
11:49 3.Player側のダメージ処理
14:58 4.Enemyのスポーン
18:01 5.ゲームClear条件
20:47 ざっくりまとめ
21:37 エンディング

向かって来る敵作ってみた!

1.敵がプレイヤーに向かって来る
2.敵がプレイヤーに接触すると爆発する
3.プレーヤーはダメージを受ける
4.敵を攻撃すると爆発して消える
5.プレイヤーHPが0になるとGame Over
6.敵を全滅させるとGame Clear

前提

攻撃アクションとダメージ表示は以前の動画で実装済みです。

1.Enemy作成

1-1.EnemyBlueprints作成

Blueprints Class → Pawn を選択。
Pawn・・・プレイヤーまたはAIによって制御可能なクラス
PawnクラスはプレイヤーまたはAIによって制御可能なクラスです。
Actor・・・アクタはワールドに配置またはスポーン可能なオブジェクト
ようするに、単なる物です。
ファイル名「BP_moveEnemy」を作成します。
※親クラスの変更
もし、親クラスの選択を間違えた時は、
ブループリンを開いて、クラス設定 > クラスオプション > 親クラス で、変更できます。

1-2.ビューポート

Enemyにコリジョンを設定します。
BP_moveEnemyを開きます。

コンポーネントを追加します。
[+追加]を押して、[Capsule Collision]を選択 (検索 collision)
CapsuleをDefaultSceneRootに重ねる(Default Rootにします)
Capsule配下にStaticMeshを追加します。
位置 -50.0
詳細パネルのスタティックメッシュを適当に割り当てます。
StaticMesh(物体)をCapsuleCollision(コリジョン)で覆います。
コリジョンを選択して、詳細パネルの形状Capsuleの大きさを設定します。
60 35ぐらい
コンパイルして保存します。

2.Enemyイベントグラフ

イベントグラフタブに移動します。
Event BeginPlay以外は削除

2-1.プレイヤーに向かって来る処理


コンポーネントを追加します。
[+追加]を押して、[FloatingPawnMovement]追加します。
FloatingPawnMovementは、
いずれかのポーン クラス用に単純な移動を提供する移動コンポーネントです。

イベント BeginPlayに AIMoveToノードを繋げます。
AIMoveToノードは、ポーンを特定の位置に移動させます
Pawnピンにselfを指定(このEnemyを指定)
Target ActorピンにGetPlayerPawn(プレイヤー)を指定指定します。

プレイヤーの位置取得に失敗した場合は
Delayノードをつないで0.2秒待ち、
もう一度プレイヤーの位置取得を行います。

これでこのEnemyプレイヤーに近づいてくるようになります。

コンパイルして保存します。

2-2.Enemyの移動範囲を設定


ModesよりNav Mesh Bounds Volume を設置します。
Brush Settings(ブラッシュ設定)で
x:y:zの大きさを調整(Enemyが移動できる範囲まで広げる)
位置 400
x:2500
y:1100
z:1500

Enemyを選択して、
「P」きーを押すと、Enemyが移動できる箇所が確認できます

2-3.敵がプレイヤーに接触すると爆発する

爆発処理を作成します。

カスタムイベントノードを配置します。
名前をBomにします。

エフェクトを付けます。
Spawn Emitter at Locationノード
[P_Explosion]
エフェクトの発生個所は自分自身なので
Get ActorLocationノードを配置TargetはSelf
エフェクトの大きさ
Scaleを3倍ぐらいに

サウンドの追加
Play Sound at Locationノードを配置
[Explosion01]
音の発生個所はEnemy自身なので
Get ActorLocationノードをつなげる

プレイヤーにたどり着いたら爆発するようにします。

AIMoveToノードのOnSuccessピンに
カスタムイベント(Bom)をつなます。

2-4.プレイヤーの特定

Enemyに接しているのがプレイヤーかどうかを特定します。

SphereOverLapActorsノードを配置
指定した球体に重なったアクタを返します。

Make ArrayノードをObjectTypeピンにつなぎます。

プレイヤーのObjectType(コリジョンのタイプ)Pawnを指定します。
Sphere Radius 範囲は3mぐらい300
0でもいい

その条件あてはまるものからプレイヤーのみに処理を行います。
For Each Loopノードを配置して、
Array Elementピンに
Cast To BP_ThirdPersonCharacter(プレイヤー)を繋げます。

2-5.プレイヤーにダメージを与える処理

プレイヤーにダメージを与えます。

Apply Damageノードを配置します。
ダメージを受けるのはプレーヤーなので、
DamagedActorピンにGetPlayerPawnノードをつなぎます。
ダメージを与えるのはEnemy自身なので、
DamageCauserピンにSelfをつなぎます。
Damage値30
処理の最後にEnemy自身を消すので、
Destroy Actorノードをつなぎます。

2-6.プレイヤーからダメージを受ける処理

プレイヤーからダメージを受けEnemyのHPが0になれば消します。
厳密には
プレイヤー → 弾 → Enemy

イベントAnyDamageノードを追加します。

与ダメージ表示用で
以前追加したブループリントインターフェース
[BPIFace]を追加します。
与ダメージ表示用が不要であれば入りません。

変数名HPをFloat型で追加します。
HP500
HPからDamage値を減算します。
HPが0以下であればアクターを消します。
Delayノードを挟んで少し調整し、最後にDestroyActorノードをつなぎます。
※ブループリントインターフェースの作り方
右クリック > ブループリント > ブループリントインターフェース
分かりやすいようにファイル名[BPIF]
BPIFファイルを開きます。
関数名「EM_Defense」
インプットの+を押して、変数を追加します。
プレイヤーからのダメージ値
変数名AtkPower Float型
アウトプットにエネミーへのダメージ値となる
変数名Damage Float型を作成。
PlayerのブループリントとEnemyのブループリントの双方にブループリントインターフェースを設定します。
ブループリンを開いて
クラスの設定 > インターフェース > 実装インターフェース
追加よりブループリントインターフェースファイルを追加します。
左のマイブループリント > インターフェースに関数名が表示されます。

3.Player側のダメージ処理


プレイヤーのブループリントを開きます。
Enemy側の処理と同じですね。
イベントAnyDamageノードを配置。
変数StaminaがプレイヤーのHPです。
プレイヤーのHPStaminaからDamageを減算してHPが0になった時の処理をします。

PrintStringノードでGameOverを表示します。

Delayノードで1秒まってもう一度現在のレベルを開きます。
GetCurrentLevelNameノードで現在のレベルの名前を取得して
OpenLevel(byName)ノードをつなぎます。

4.Enemyのスポーン

Enemyの出現ポイント

右クリック > ブループリントクラス > アクター

ファイル名を「BP_Enemyspawn」
ファイルを開きます。
イベントグラフで
イベントBeginPlayノードにDelayノードをつなぎます。

Random Float in Rangeノードを配置してつなぎます。
最小と最大の間のランダムな数値を生成します。

2〜5秒待った後に
スポーンするActorを出現させるようにします

Spawn Actor from Classノードをつなぎます。

Classに出現させるActorを指定します。

SpawnTransformに
出現させる状態を指定します。
Make Transformノードをつなぎます。
場所、向き、大きさを指定
今回は、場所はこのスポーンアクターの場所なので
GetActorLocationノードをつなぎます。

スポーンさせるEnemyブループリントを開きます。
詳細パネル > ポーン > AutoPossessAIを
Placed in World or Spawned
に変更します。
ポーンが作成されるたびにAIで自動的に処理されるようにします。

5.ゲームClear条件

出現しているEnemyをすべて倒すとGameClearとする

レベルブループリントを開きます。
今回はTikを使って
でレベル上にEnemyが居ないか監視するようにします。

イベントTickノードに
先頭にDelayノードをつなぎます。
Enemyが3秒のランダムタイムでスポーンするので、
最初の4秒は監視しないようにします。

GetAllActorsOfClassノードをつなぎます。
GetAllActorsOfClassノードは
指定したクラスで
ワールド内のアクタすべてを検索します。
操作速度が遅くなるため、使用には注意が必要です。
例えばフレームごとに使用しないでください。

今回イベントTickノードにつなぎますが、本来やっちゃダメなのかも

ActorClassに監視したいEnemyクラスを追加します。

ブランチノードをつなぎます。
Enemyが0体なったらTrueに処理を渡すようにします。

OutActorピンにLengthノードをつないで
条件式≦小なりイコールをつなぎます。
ブランチノードにつなぎます。

True処理は
ゲームクリア用ウィジェットを表示させます。

ざっくりまとめ