BLOGブログ

2022.02.18UE4UE/ 初心者向けUE/ Blueprint

[UE4] プレイヤーを検知する敵キャラクターを作る

執筆バージョン: Unreal Engine 4.27

第17回ぷちコンのテーマ「かいとう」にちなんで、“プレイヤーを検知する機能”を作成します。
ハンズオン形式で書いたので、ぜひ真似してつくってみてください。

完成イメージはこちら!
※ThirdPersonテンプレートを使っています。

目次

・準備
・検知機能の作成
・検知した時にアイコンを表示する
・完成
・おまけ


準備

作成に入る前に下記のものを用意します。
・作成したファイルをまとめておくフォルダ
・敵キャラクター
・プレイヤーを検知した時に表示するアイコン画像

■フォルダの作成

本記事で作成するファイルをまとめておくファルダを作成します。

フォルダ名は”EnemyBP”にしました。

■敵キャラクターの作成

ThirdPersonCharacterをコピーして敵キャラクターに仕立て上げます。
Content→ThirdPersonBP→Blueprintsの”ThirdPersonCharacter”をコピー(Duplicate)します。

ファイル名は”Enemy”にしました。

EnemyをEnemyBPに移動します。
EnemyをEnemyBPにドラッグアンドドロップしてください。

Move Hereを選び、ファイルを移動させます。

Enemyを移動させることができました!

敵キャラクターと認識しやすいように色を変更します。
適用されているマテリアルを変更することで色変更が可能です。
Enemyを開いて、適用されているマテリアルを確認しましょう。

適用されているマテリアル”M_Male_Body”を確認できました。

Enemyは、ThirdPersonCharacterをコピーしたものです。
なので、ThirdPersonCharacterもM_Male_Bodyが適用されています。

M_Male_Bodyの色を変更してしまうと、プレイヤーの色も変わってしまいます。
そこで、M_Male_Bodyをインスタンス化します。
※マテリアルインスタンスの使用方法についてはこちらをご覧ください。
[UE4]Material Instanceの基本的な使い方|株式会社ヒストリア

ファイル名は”MI_Male_body”にしました。
Enemyのときと同じように、EnemyBPフォルダに移動させておいてください。

マテリアルインスタンスのBodyColorを変更して、色を決めます。
好きな色にしてみてください。

本記事では赤色にしています。

マテリアルインスタンスを適用して、色を変えてみましょう。
Enemyを開いて、今度は虫眼鏡ではなくマテリアル名をクリックしてください。

最後に、EnemyのBlueprintから必要のないノード、コンポーネントを消して完成です!
※これらはThirdPersonCharacterに入っていたPlayerの操作に関する処理なので、Enemy側では消しましょう。

■アイコンの用意

頭上に表示するアイコンの画像を用意して、EnemyBPに追加しましょう。
ビックリマークや驚いたマークなど好きなアイコンをつかってみてください。

コンテンツ ブラウザ から [Import (インポート)] ボタンをクリックして、
使いたい画像を選択することでインポートが可能です。

これで準備完了です!


検知機能の作成

ここでは、検知機能は「Enemyの顔から真っすぐ先にプレイヤーが居たら検知する」という処理にします。
下記の画像の赤い線が、検知するための処理を可視化したものです。
こちらは「ライントレース」という機能を使って実装していきます。

■ライントレースの実装

今回使用する「LineTraceByChannel」というノードは、始点と終点の位置を指定して、
始点から終点にレイ(光線)を飛ばして、当たったオブジェクトを返すノードです。

まずはEnemyのEventGraphを開いてください。
最初に判定線の長さを定義するための変数を作成します。

変数名は”Distance”にしました。
変数の型をFloatに変更します。

確認のため、一度コンパイルしてみましょう。

コンパイルすることで数値を入れられるようになります。
数値は後程入れるので、今は0のままで問題ありません。

冒頭で紹介した”LineTraceByChannel”を追加します。

全体像はこのようになります。

始点を決めている部分です。
Enemyの顔からライントレースを伸ばすために、Enemyの現在地にZの値(腰から顔までの距離)を足しています。

終点を決めている部分です。「始点からEnemyの正面方向に離れた位置」が終点になります。
離れる距離は、Distanceの値で調整します。今回は、Distanceの値を”500”にしました。
正面方向に離れた位置を取得するために、GetActorForwardVectorにDistanceを掛け算します。
始点を原点にして、Distanceの値分離れた位置を終点にしたいので、計算の最後に始点の値と足し算します。

ライントレースをデバッグ用に表示するために、LineTraceByChannelの「Draw Debug Type」を「For Duration」に変更してみましょう。
毎フレームこの部分の処理は通るので、1回の処理では一瞬表示されればよいので、「Draw Time」は「0.0」にしておきます。

レベルにEnemyを配置して、再生してみましょう。
Enemyから赤い線が伸びているはずです。

確認ができたら、「DrawDebugType」は「None」に戻しておきましょう。

■検知したアクターをログ表示する

実際にライントレースが検知しているのか確認してみましょう。
ライントレースがヒットした時、画面左上にHit!の文字が表示されるように、”PrintString”を追加します。
表示される文字をチェックしやすいように、PrintStringのDurationを0.0にしてください。
ヒットしていないときは、Falseに処理が流れるので何も起こりません。

プレイヤーを操作して、Enemyの前に立ってみてください。

プレイヤーにヒットしないと思います。
プレイヤーの当たり判定が、ライントレースを無視する設定になっているからです。
ライントレースが当たるように設定を変更します!

プロジェクトセッティングを開きます。

VisibilityのIgnore(無視)にチェックが入っていると思います。
これをBlockに変更することで、ライントレースに当たるようになりました。
もう一度プレイヤーを操作して、Enemyの前に立ってみてください。

ライントレースがヒットするようになりました!
画面左上にもHit!の文字が表示されています。

しかし、このままでは壁などのプレイヤー以外のアクターも検知してしまいます。
次のセクションでは、検知している相手がプレイヤーなのかどうか判定する機能を作成します。

■検知した相手がプレイヤーかどうか判断する

「プレイヤーにヒットした時だけ、アイコンを表示したい」ので、検知した相手がプレイヤーなのか判断する機能を作成します。

OutHitからヒットした相手の情報を取得することができます。
LineTraceは、BreakHitResultとセットで使うことが多いです。

BreakHitResultからHitActorの情報を取得します。
ActorHasTagで”Player”というTagを持っているか確認することができます。

ThirdPersonCharacterを開いて、Tagの設定をします。

これで、プレイヤーだけEnemyの検知に引っかかるようになりました!
ライントレースが壁に当たるようにEnemyを移動して、確認してみてください。
※確認が取れたら、PrintStringは必要ないので消してください。

■検知機能完成!

これで検知機能の完成です!


検知した時にアイコンを表示する

プレイヤーを検知した時、敵キャラクターの頭上にアイコンを表示する機能を作成します。

■表示するWidgetの作成

EnemyBPにWidgetBlueprintを作成します。
ファイル名は”Icon_Exclamation”にしました。

事前に用意していたアイコン画像を追加します。

追加したImageに用意した画像を設定します。

潰れた画像を元に戻します。

Widgetの中心に画像を配置します。
Anchorsを中央にすることで、座標の原点が中央になります。

Imageの基点は左上です。
なので、PositionX,Yで調整する必要があります。

Image Sizeの半分、位置をずらします。(例:200 → -100)
これでIcon_Exclamationは完成です!

■敵キャラクターにアイコンを追加する

Enemyに戻り、アイコンの大きさと位置の調整をしていきます。
Icon_Exclamationを表示するために、Widgetコンポーネントを追加してください。

WidgetコンポーネントにIcon_Exclamationを設定します。

用意した画像によっては大きすぎる場合があります。
その場合は、Icon_Exclamationに戻ってImageSizeを変更します。

Widgetコンポーネントを頭上の位置に動かします。

プレイして、Enemyの頭上にアイコンが表示されているのを確認してみてください。

■アイコン表示機能を追加

アイコンの表示・非表示機能を作成します。
Visibleのオンオフで、コンポーネントの表示・非表示を決めることができます。
発見した時に表示したいので、デフォルトは非表示にします。

プレイして、Enemyの頭上にアイコンが消えているのを確認してみてください。

Playerタグで選別した先に処理を追加します。
タグを持っているかどうかで、Visibleが切り替わるようにします。

これで、プレイヤーが検知に引っかかるとアイコンを表示するようになりました!
プレイして確認してみてください。

■アイコンの向きを整える

表示されたアイコンは、横から見ると見づらい状態です。
最後に、プレイヤーカメラに対してアイコンが正面を向くようにします。

LineTraceの前に追加します。
Widgetがプレイヤーカメラの方を向くように、FindLookatRotationのTargetにプレイヤーカメラの位置を繋げます。

完成

完成したノードの全容になります。

モデルを差し替えれば、監視カメラなんかも作れると思います。
是非、ぷちコンでお役立てください!
※今回は敵キャラクターの実装を想定して、ThirdPersonCharacterをコピーして作成しました。なので、BlueprintクラスがCharacterになっています。
ただ、Characterクラスでないと動かないような機能は実装していません。なので、監視カメラなどを作成する際、BlueprintクラスをActorで作ってもらって問題ありません。


おまけ①

今回、動かすロジックは組んでいません。
UnrealEngineには、AIキャラクターを作成するビヘイビアツリーという機能があります。
徘徊しながら、プレイヤーを見つけたら追いかけるといった機能も実装できます。
本記事の内容より少し難しくはなりますが、挑戦してみてください!

参考記事:[UE4] ビヘイビアツリー(BehaviorTree)の使い方 入門編|株式会社ヒストリア


おまけ②

ライントレースで検知できる範囲が狭すぎると感じた方もいらっしゃると思います。
そこで、扇形にライントレースを何本か飛ばす方法を紹介します。
難易度が上がりますが挑戦してみてください!