このチュートリアルのパートでは、プレイヤーを検知し、追跡し、ダメージを与える敵を作成します。 さらに、敵はダメージを受けたり、ナビゲーション メッシュを使用して環境内を移動して障害物を避けたりすることができます。
これまでのチュートリアルと同様に、まずブループリント ビジュアル スクリプティング システムを使用して敵のロジックを作成します。 次に、ナビゲーション メッシュを作成して、AI がナビゲートできる環境を定義します。 ナビゲーション メッシュは、さまざまな AI キャラクターがゲームプレイ中にナビゲートできるマップ上の特定のゾーンとエリアを設定します。
敵を作成する
前回のチュートリアルでブループリントで実行した作業に加えて、今度は、敵を視覚的に表現し、アニメーション ブループリントを使用してアニメーションを再生するオブジェクトを追加します。 アニメーション ブループリントはプロジェクト ファイルで提供されているため、最初から作成する必要はありませんが、敵キャラクターのブループリントとアニメーション ブループリントを統合する方法を習得することが重要です。
まず、Enemy ブループリントを作成します。 次の手順を実行します。
コンテンツ ブラウザ に行き、「Content」>「AdventureGame」>「Blueprints」>「Characters」に移動します。
コンテンツ ブラウザの空いている場所を右クリックし、[Blueprint Class (ブループリント クラス)] をクリックします。
新しいウィンドウで、ベース クラスとして [Character (キャラクター)] を選択します。
このクラスに「BP_Enemy」という名前を付け、ダブルクリックしてブループリント エディタで開きます。
ブループリントを作成すると、ブループリント アセットの一部でブループリントの機能を定義するブループリント クラスも作成します。 機能を追加するときは、ブループリント クラスを編集しています。 この例では、「BP_Enemy」という名前のブループリント アセットを作成しています。これは、ブループリント クラスと同じ名前を使用しています。
基本クラスは、新しいブループリント クラスで利用できる、事前に作成された機能を備えたテンプレートのように表示されます。 この場合、キャラクター基本クラスには、動作や視点のためのカメラの回転など、ゲーム キャラクターに関連した機能があります。 この基本クラスを使用することで、事前作成済みの機能を利用し、その機能の再作成を回避することができます。
プレイヤーのブループリントである BP_AdventureCharacter も キャラクター 基本クラスを使用するため、プレイヤーと敵の両方のキャラクターは、同じ基本機能を備えており、再利用できます。
BP_Enemy ブループリントが開いている状態で、Viewport (ビューポート) タブを開いて Components (コンポーネント) パネルを確認します。 リストの一番下に キャラクター移動 (CharMoveComp) コンポーネントがあります。 これは、キャラクター ベース クラスの一部である最大移動速度など、移動に関連する独自の関数や変数を持つコンポーネントです。 このコンポーネントは、プロジェクト内の敵に似たような機能を作成する際に使用できます。
3D モデルを敵に追加する
まず、新しいコンポーネントを追加します。 次の手順を実行します。
[Skeletal Mesh (スケルタルメッシュ)] コンポーネントを選択し、ウィンドウの右側にある [Details (詳細)] パネルの下を確認します。 [Mesh (メッシュ)] カテゴリを見つけ、[Skeletal Mesh Asset (スケルタル メッシュ アセット)] の横にあるドロップダウンをクリックします。
リストから「SKM_Manny_Simple」モデルを検索して選択します。 これにより Mannyモデルがブループリントに割り当てられます。
次に [Animation (アニメーション)] カテゴリを見てみましょう。 [Anim Class (アニメーション クラス)] の横のドロップダウンをクリックして、ABP_Unarmedアニメーション ブループリントを割り当てます。 このコンテキストにおける ABP は「アニメーション ブループリント」を表しています。
アニメーション ブループリントが敵で適切に機能するように変更します。
敵メッシュの Anim Class プロパティで、ABP_Unarmed の横にある [コンテンツ ブラウザにアセットをブラウズ] をクリックします。
ABP_Unarmed アニメーションブループリントをダブルクリックして開きます。
Sequence ノードの Then 1 ピンの後に続くロジックのグループに移動します。 敵キャラクターが動くのを妨げる加速度チェックは無効にする必要があるため、And ノードと Set Should Move ノード間のワイヤーを削除します。
Greater than (>) ノードの出力ピンを Set Should Move に接続し、加速度のチェックをバイパスします。
このブループリントを保存してコンパイルし、閉じます。
これで、敵キャラクターは [ビューポート] タブでアイドル アニメーションを再生しているはずです。
ビューポートでは、敵キャラクターを囲むカプセル形状が表示されます。 Capsule コンポーネントはコリジョン コライダーの視覚的な表現で、壁、地面、プレイヤー キャラクターなど、他のオブジェクトとのコリジョンを検出するために使用できます。
ビューポートでキャラクターが地面レベルからオフセットされていて、カプセル コンポーネントに位置合わせされていないことがわかります。 ゲームプレイ中に位置がずれることがあります。 キャラクターのメッシュが Capsule コンポーネントに適切に揃うように、キャラクターを下に動かして、足がカプセル コンポーネントの下部に接するようにします。
Mesh (メッシュ)コンポーネントを選択し、3D モデルをハイライトします。 詳細パネルで、トランスフォーム カテゴリの Location (位置) フィールドを使用して、最後のフィールドの青色の Z 軸 を変更します。 値を「-96」に設定します。 これによりメッシュがカプセル コライダーの下部に移動し、ゲーム内で敵が地上から浮いたりしないようになります。
キャラクターの前面が青色の矢印の方向を向いていることを確認します。これは、[Components (コンポーネント)] パネルでは 矢印コンポーネント (Arrow) として表示されます。 矢印は、どちらの方向がブループリントの前面であるかを示しています。
[Components (コンポーネント)] (コンポーネント)]パネルで Arrowコンポーネントを確認します。 この矢印は、ビューポートタブでもライト ブルーの矢印として表示されます。
矢印コンポーネントは、キャラクターが全方向に正しく移動するために、どの方向を向いている必要があるかを示します。 矢印の方向はキャラクターの前方を表しています。
そのため、それを念頭に置いて、もう一度 Mesh (メッシュ) コンポーネントを選択し、[Details (詳細)] パネルを介してキャラクターを Z 軸 を中心に回転させます。これは、[Transform (トランスフォーム)] の最後のフィールドです。 「-90」に設定すると正しく回転します。
| 誤った向き | 正しい向き |
|---|
3D モデルのマテリアルを変更する
機能の作成に進む前に、敵モデルの色を赤に変更しましょう。 これにより、プレイヤーと区別して、現在の白色ではなく、敵のように見えます。
[Details (詳細)] パネルの [Materials (マテリアル)] セクションに 2 つの要素があるのがわかります。 MI_Manny_01_New は、上腕、脚、頭部など、敵モデルのさまざまな部分に影響を及ぼすマテリアルです。 MI_Manny_02_New は、前腕と胴体に影響を与えるマテリアルです。
[Element 0] プロパティの横にあるフォルダと虫眼鏡のような [Browse in Content Browser (コンテンツ ブラウザでブラウズ)] ボタンをクリックします。 これにより、コンテンツ ドロワーが開き、選択したマテリアルがブラウズされます。 2つ目のマテリアルのMI_Manny_02_Newもここにあるのがわかります。
MI_Manny_01_New アセットを右クリックして、[Create Material Instance (マテリアル インスタンスの作成)] をクリックします。 これにより、選択したマテリアルのインスタンスが作成されます。 マテリアル インスタンスは親マテリアルからすべてを継承し、変更したいパラメータをオーバーライドすることができます。 たとえば、色を変更しても、マテリアルの光沢など、その他の設定はすべて同一に維持されます。
新しいマテリアル インスタンスの作成時には、Unreal Engine により、MI プレフィックスを使用した新しいアセットの名前が自動的に割り当てられます。 この場合、MI はマテリアル インスタンスを表します。 既存のマテリアルからブランチし続けるためのマテリアル インスタンスやマテリアル インスタンスを作成できます。
マテリアル インスタンス アセットの名前を「MI_Enemy_01」にし、ダブルクリックして開きます。
右側の [Detail (詳細)] パネルで、01 - BaseColor を展開し、Paint Tint プロパティを切り替えます。 [Paint Tint] プロパティの横にある色見本をクリックし、[Color Picker (カラー ピッカー)] ウィンドウを使用して赤色を選択します。
このチュートリアルでは、ホット レッド カラーを使用することにしました。これを使用するには、カラー ピッカーの右下隅にある [Hex sRGB] フィールドにカラー コード F60E6EFF を貼り付けることで使用できます。
[Material (マテリアル)] ウィンドウの左上隅にある [Save (保存)] ボタンをクリックし、マテリアル ウィンドウを閉じます。
次に、コンテンツ ブラウザに再度移動し、今度はMI_Manny_02_Newアセットを右クリックして、[Create Material Instance (マテリアル インスタンスの作成)]をクリックします。
このマテリアル インスタンスに「MI_Enemy_02」という名前を付け、このマテリアルでも前の手順を繰り返します。
上記の手順を繰り返すと、2 つのマテリアル インスタンス「MI_Enemy_01」と「MI_Enemy_02」が作成されます。 マテリアル エディタ windows の [Save (保存)] ボタンを使用して、両方のマテリア インスタンス アセットを保存します。
次に、これらのマテリアルを敵キャラクターに割り当てます。 BP_Enemy ブループリントをブループリント エディタのウィンドウで開き、[Detail (詳細)]パネル から [マテリアル] セクションに移動します。 [Element 0] のドロップダウンをクリックして、作成した新しいマテリアル「MI_Enemy_01」を選択します。 [Element 1]では「MI_Enemy_02」マテリアルを選択します。
今度は、新しいマテリアル インスタンス アセットを使用して、敵キャラクターが赤色になります。
ゲームプレイ開始時に敵を設定する
敵の準備ができたので、ゲームプレイ機能を作成します。 まず、敵がスポーンされたときに必要な敵のプロパティを設定します。
次の手順を実行します。
BP_Enemy のブループリント エディタ ウィンドウで、[Viewport (ビューポート)] タブの隣にある EventGraph (イベント グラフ) タブに移動します。 デフォルトでは、Event BeginPlay、Event ActorBeginOverlap、および Event Tick という 3 つのイベントが表示されます。 ActorBeginOverlap を選択し、このチュートリアルでは不要であるため削除します。
まず、[Components (コンポーネント)] パネルを使用して、[Character Movement (キャラクターの移動)] コンポーネントをイベント グラフにドラッグします。 これにより、Character Movementというノードが作成されます。 このノードのピンをドラッグして、Set Max Walk Speed ノードを作成します。
Set ノードの緑色の Max Walk Speed ピンを右クリックし、コンテキスト メニューの [Promote to Variable (変数へ昇格)] オプションを選択します。 これにより、新しい変数が作成されます。この変数は、ブループリント エディタの左側にある [My Blueprint (マイ ブループリント)] パネルの変数リストの下に表示されます。
変数の名前をMax Speedにします。 変数の横にある目のアイコンをクリックして、これを編集可能なパブリック変数に設定します。 ブループリントをコンパイルし、[Details (詳細)] パネルで Max Speed のデフォルト値を「200」に設定します。
この変数はパブリックであるため、レベルに敵を追加するときにレベル内でこの値を設定することができます。 しかし、値を変更するのを忘れてデフォルト値が「0」に設定されていると、敵は移動できなくなります。 デフォルト値を「200」に設定することで、敵が移動するのに十分な移動速度を確保することができます。
[Variables (変数)] リストで、Float 型の「CurrentHP」という名前の新しい変数を追加します。
さらに「Eliminated」という名前の変数を追加し、その型をブーリアンに変更します。
[Variables] リストから [CurrentHP] 変数をイベント グラフにドラッグし、コンテキスト メニューの [Set Current HP] オプションをクリックします。 Set Max Speed ノードの実行ピンをドラッグし、Set Current HP ノードの実行ピンに接続します。
Set Current HP ノードで、Current HP の浮動小数ピンを右クリックして、Promote to Variable をクリックします。
この変数の名前を「TotalHP」に変更します. 型を Float に設定し、目のアイコンをクリックして公開、編集可能にします。 [Details(詳細)]パネルで [Category(カテゴリ)] を[Setup (設定)]に設定します ブループリントをコンパイルし デフォルト値を「100」に設定します。
重要なのは、敵のヘルス値を追跡する 2 つの変数を設定することです。1 つの変数として、Total HP は敵キャラクターの開始時のヘルス値を保存し、Current HP 変数は敵がいる時点でのヘルス値を追跡し、ダメージを受けた後などに実行します。 Total HP 変数を公開すると、レベル内の敵キャラクター ブループリントの各インスタンスからこの値を調整できるようになります。つまり、それぞれの敵の強さを調整し、プレイヤーが倒すのを難しくしたり簡単にしたりできるようになります。
このイベント グラフではプレイヤー キャラクターに対して多くのアクションを実行します。次はプレイヤーへの参照を変数として保存します。 [Variables (変数)] リストで、「PlayerRef 」という名前の新しい変数を作成し、その型を [Character (Object Reference)] に変更します。
プレイヤーを参照する必要があるたびに Get Player Character 機能を呼び出すよりも、キャラクター オブジェクトの参照変数を作成するほうがプロジェクトのパフォーマンスの面で優れています。
Set Current HP ノードの後に、Set PlayerRef ノードを接続します。 そのプレイヤー参照入力ピンで、Get Player Character ノードを接続します。 このノードの Player Index (プレイヤー インデックス) の値が 0 であることを確認します。 これは、レベルにスポーンされた最初のプレイヤー キャラクターのデフォルトのインデックスです。
ビルドしたロジックをイベント BeginPlay 機能ノードに接続します。 イベント グラフは次のようになります。
敵がプレイヤーを追跡するようにする
次に、敵をプレイヤーに向かって移動させるロジックを作成します。 これを行うには、カスタム イベントを作成します。このイベントは、BeginPlay などの他のイベント ノードと似ていますが、ロジックを再作成することなくブループリントのどこからでも呼び出すことができるカスタム イベントです。
カスタム イベントを作成するには、次の手順を実行します。
イベント グラフ内の任意の場所を右クリックして、検索フィールドに「Custom Event」と入力します。 リストで Add Custom Event オプションをクリックし、このイベントに「MoveToPlayer」という名前を付けます。
新しく作成した MoveToPlayer イベント ノードのピンをドラッグし、検索フィールドにAI MoveToと入力します。 AI MoveToノードを選択して作成します。
AI MoveTo ノードは、AIController を持つポーンが特定の場所に移動するために使用できるイベントです。 この場合、敵をプレイヤーに移動させるために使用します。
AI MoveTo ノードで、Pawn ピンをドラッグし、検索フィールドに「Self」と入力します。 [Get a reference to self] オプションを選択し、ゲーム内でこのブループリントのアクタを参照するノードを作成します。
次に、AI MoveTo ノード の トターゲッ アクタピンをドラッグして、 Get PlayerRef ノードを作成します。
この場合、どのアクタを移動するかを定義するために使用される Selfノードを使用して、この Enemy としてポーンを定義します。 続いて、Target Actor (ターゲット アクタ) をレベルのプレイヤー キャラクターに設定します。
AI MoveTo ノードには、On Success イベントと On Fail イベントが付属しています。 これらを使用して、敵がプレイヤーに到達した場合、または失敗した場合の動作を定義します。
On Success ピンをドラッグして、Delay ノードを作成します。
Delay ノードの Duration (期間) ピンを右クリックして、Promote to variable (変数に昇格) を選択します。
変数に「WaitAtDestination」という名前を付けて、デフォルトでその型を「Float」に設定します。
ブループリントをコンパイルし、WaitAtDestination 変数を選択して [Default Value (デフォルト値)] を「5」に変更します。 目のアイコンをクリックして編集可能にしカテゴリを[Setup (設定)]に変更します。
次に、イベント グラフでDelay ノードのExecピンをドラッグして、Move To Player ノードを作成します。 これにより、作成した Move To Player イベントは、敵がプレイヤーに到達しても一定の時間が経過した後に実行されます。
次に、AI MoveTo ノードで、On Fail ピンをドラッグして、新しい Delay ノードを作成します。 このノードの Completed ピンをドラッグして、Move To Player ノードを作成します。 この Delay ノードの[Duration (期間)]フィールドは「0.2」のままにします。
これにより、敵がプレイヤーに到達しない場合でも敵が移動し続けるようになります。
Event BeginPlay ノードをもう一度見てみましょう。 このシーケンスの最後に、Set Player Ref ノードの後に Move To Player ノードを接続して、このイベントをトリガーします。 これは、ゲームの開始時に敵を動かし、敵の動きをテストできるようにします。
次のようになります。
これでブループリント全体は次のようになります。
プレイヤーにダメージを与える
次は、敵がプレイヤーに到達した場合に、プレイヤーにダメージを適用します。 このチュートリアルでは、プレイヤーと接触すると自己破壊する敵を作成するため、プレイヤーにダメージを与えた後にその敵を排除するロジックを追加します。
次の手順を実行します。
[Components (コンポーネント)] パネルで、Capsule コンポーネント (CollisionCylinder) を選択します。
[Details (詳細)] パネルの Events (イベント) セクションで、[On Component Hit] の横にある [Add (追加)] (+) を使用します。
これにより、イベント グラフに新しいイベント ノードが作成され、コンポーネント (この場合は選択した Capsule コンポーネント) が何かにヒットしたときに実行されます。
On Component Hit ノードのピンをドラッグし、Branch ノードを作成します。 Branch ノードの Condition ピンをドラッグして、On Component Hit ノードの Other Actor ピンにドラッグすると、新しいノードの作成を促すプロンプトが表示されます。
Equal ノードを作成します。このノードは、On Component Hit ノードによって検出されたその他のアクタが意図したアクタ (この場合はプレイヤー キャラクター) であることをチェックします。 Equal ノードの Select Asset ピンをドラッグし、PlayerRef 変数への参照を追加します。
これにより、敵の Capsule コンポーネントがゲーム内で何かにヒットしたときにイベントがトリガーされます。 このイベントは、Capsule コンポーネントがヒットした他のオブジェクトがプレイヤー キャラクターであることを確認します。 この情報を使用して、ダメージをプレイヤーに適用します。
このチュートリアルでは、プレイヤーを 1 回攻撃すると自爆する敵を作成します。 プレイヤーへのダメージを 1 回だけ与えられるようにするには、Branch ノードの True ピンからドラッグし、Do Once ノードを作成します。
Do Once ノードの Completed ピンからワイヤーを引き出して、Apply Damage ノードを作成します。 Damaged Actor ピンをドラッグし、PlayerRef 変数への参照をつなげて、ダメージを与える対象アクタとして割り当てます。
次に、Base Damage ピンを右クリックして、Promote to Variable (変数へ昇格) を選択します。 変数リストで Base Damage の目のアイコンをクリックして編集可能にし、カテゴリを Setup (設定) に変更します。 ブループリントをコンパイルし デフォルトのダメージを「25」に設定します
次に、Eliminated 変数を変数リストからイベント グラフにドラッグし、Set (設定) を選択します。
Apply Damage ノードの Exec ピンを Set Eliminated ノードに接続します。
Set Eliminated ノードの Eliminated プロパティを true に切り替えます。
Set Eliminated ノードのExecピンをドラッグして、Delay ノードを作成します。 Durationを「2.0」に設定します。
次に、Delay ノードの Exec ピンをドラッグして、Destroy Actor ノードを作成します。 Target プロパティは、デフォルトでは self に設定されています。
敵がプレイヤーに衝突すると、プレイヤーにダメージを適用し、2 秒間のディレイの後、敵をキルします。
この段階では、敵はプレイヤーに向かって走って、ダメージを与えて、自爆できます。 ただし、プレイヤーと敵との距離や、プレイヤーと敵の間に壁などの障害物があるかどうかは考慮されません。 そのため、敵は常にプレイヤーを追跡します。
距離と障害物ロジックを追加する
このドキュメントの次のセクションでは、敵がプレイヤーに十分近づいた場合にのみ検出できるように、最大検出距離を設定する方法について説明します。 最後に、敵が壁を通してプレイヤーを視認できない機能を作成します。 そのため、プレイヤーを敵の視界に入れる必要があります。 まず、敵とプレイヤーの間をライン トレースする新しい関数をブループリント ライブラリに作成します。
ライン トレースを使用して視線と距離を計算する
ライントレースは ゲーム開発においてよく使用される手法です。 ライン トレースは、ランタイム時に他のゲーム オブジェクトやアクタと交差し、検出する、ソース アクタから見えないラインを描画します。 その後、ライン トレースで検出されたアクタやゲーム オブジェクトを使用して、ゲーム ロジックを有効にすることができます。 このチュートリアルでは、敵キャラクターからのライン トレースを使用する設定について説明します。これにより、プレイヤー キャラクターが敵の視界に入ったときを検出します。 ライン トレースの詳細については、「レイキャストによるトレース」ドキュメントを参照してください。
ライン トレースを使用してプレイヤーまでの距離と視線をテストする関数を設定するには、次の手順を実行します。
コンテンツ ブラウザで、「Core」フォルダに移動して、BPL_FPGame ブループリント ライブラリを開きます。
「fnBPLFindPlayer」という名前の新しい関数を追加する
新しい関数の [Details (詳細)] パネルで、プロパティの [Inputs (入力)] セクションに移動し、[Add (+)] を使用して次の入力タイプを追加します。
プレイヤー参照 (ポーンオブジェクト参照)
開始地点 (Vector)
最大検出距離 (Float)
デバッグ (Boolean)。
これらの入力を追加すると、fnBPLFindPlayer 関数ノードに、各変数に対応するピンがあることがわかります。
次に、機能の [詳細パネル] で、プロパティの[Outputs (出力)]セクションに移動し、[Add (+)]を使用して、Player Found ブーリアン変数を作成します。
Player Found Output 変数を追加すると、Player Found Output 変数を含む新しい Return ノードがグラフに作成され、Entry ノードに接続されます。
最後に、[My Blueprint (マイ ブループリント)] パネルで、[Local Variables (ローカル変数)] セクションに移動し、Add (+) でローカルの PlayerFound (ブーリアン) 変数を作成し、そのデフォルト値が False であることを確認します。
次に、プレイヤー入力のエラー チェックを追加する必要があります。 このチェックを追加するには、次の手順を実行します。
Alt キーを押したまま Entry ノードまたは Return ノードのいずれかの実行ピンをクリックして、Entry ノードと Return ノード間のワイヤーを削除します。
Function Entry ノードの後に、Is Valid ノードを作成して接続します。 ノードを作成した後、Entry ノードからプレイヤー参照ピンをドラッグし、Is Valid ノードの Input オブジェクト ピンに接続します。Is Valid はどのブループリントでも使用できるライブラリ機能であり、プレイヤー参照はこの機能にとって適切に実行されるため、エラーを回避するために無効なプレイヤーの参照に対する条件を追加します
Is Not Valid exec ピンを Return ノードに接続します。 Found 値では、PlayerFound 変数への参照を接続します。 これは関数を終了し、PlayerFound=False を敵のイベント グラフに返します。
ライン トレースを設定するには、以下の手順を実行します。
プレイヤーが有効な場合、機能はライン トレース オブジェクトを実行し、PlayerFound を返します。 Sequence ノードを追加してロジックを整理します。
Sequence ノードの [Then 0] ピンからドラッグし、Line Trace By Channel ノードを追加します。注:このノードについての情報が表示されます。 チャンネル別とは? これに関するリンク先のドキュメント
Line Trace By Channel ノードを設定します。
Entry ノードから Start Location ピンをドラッグし、Line Trace By Channel ノードの Start 入力ピンに接続します。 敵キャラクターの位置をライン トレースの開始点として使用します。
次に、Entry ノードのプレイヤー Reference ピンをグラフ内の任意の場所にドラッグすると、ブループリント ノードのコンテキスト メニューが開きます。 コンテキスト メニューを使用し、Get Actor Location ノードを検索して作成します。 これにより、プレイヤーの参照をターゲット入力として使用する新しいノードが作成されます。 これにより、ライン トレースがそのプレイヤーの場所で終了します。
Line Trace By Channel ノードで、ドロップダウン メニューを使用して [Trace Channel] プロパティを [Camera] に設定します。
次に、ライン トレースのヒット結果を使用してプレイヤーとヒット距離をチェックする機能をビルドします。次の手順を実行します。
ライン トレースの Out Hit ピンからドラッグして、Break Hit Result ノードを追加します。 ライン トレースがオブジェクトにヒットすると、多くの情報が収集されますが、このロジックのためにいくつかの特定の値のみを使用する必要があるため、Break Hit Result ノードを使用して、データを返されたデータの個々のコンポーネントに分割する必要があります。
Break Hit Result ノードで、下部の矢印をクリックすると、その他のオプションが表示されます。 この機能の目的は、プレイヤーが敵との一定の距離内にいて視界上にいるかどうかを判断することです。そのため、Hit Actor を使用してプレイヤーかどうかを確認し、Trace Start と Trace End を使用して距離を測定しますヒットオブジェクトにバインドしました。
Hit Actor ピンからドラッグして Equal 演算子ノードを追加します。 下の入力では、プレイヤー Reference 関数の入力への参照を接続します。
Distance (Vector) ノードを作成します。 V1 を Trace Start に接続し、V2 を Trace End に接続します。注:ベクターは、3D 空間でのオブジェクトまたはポイントの位置を表す X、Y、および Z の値のセットです。 Distance ノードは、これら 2 つのポイントの間の距離を計算します。その結果が float 値になります。
Distance ノードの Return 値からドラッグし、Less (<) ノードを追加します。 下の入力では、Max Detection Distance 関数の入力への参照を接続します。
AND (Boolean) ノードを作成し、Equals (==) と Less (<) ノードの両方のブール出力を AND (Boolean) ノードの入力ピンに接続します。このロジックでは、ライン トレースがライン トレースをヒットすると、Player Reference と等しい場合、トレースの開始 (敵) と終了 (ヒット オブジェクト) の間の距離が Max Detection Distance よりも小さい場合は、AND ノードは True を返します。
AND ノードの出力からドラッグし、Branch ノードを追加して、次のようにノードを設定します。
Line Trace By Channel の後に実行されるように接続します。
Branch ノードの [True] 実行ピンから、Set 変数ノードを作成して、ローカルの PlayerFound 変数を true に設定します。
Branch ノードの False 実行ピンから、Set 変数ノードを作成してローカルの PlayerFound 変数を False に設定します。
ライン トレース ロジックが完了したので、Sequence ノードに戻り、その [Then 1] ピンを [Return ノード] に接続します。 関数を終了し、PlayerFound の結果を敵のブループリントに送信します。
Line Trace のデバッグ用ビジュアルは、レベル エディタから簡単にオンとオフを切り替えることができるようにする必要があります。 ただし、Line Trace ノードでは、Draw Debug 型 リストから 1 つのオプションのみを選択できます。 Select ノードを使用して、編集可能な Debug ブーリアン変数を Draw Debug 型オプションの 2 つに接続できます。
ライン トレースにカスタマイズ可能なデバッグ オプションを設定するには、次の手順を実行します。
Line Trace By Channel ノードの [Draw Debug 型 (デバッグ 型の描画)] ピンからワイヤーを引き出して、Select ノードを作成します。
Select ノードのインデックスピンを Entry ノードの Debug 機能の入力に接続します。Select ノードのインデックスはワイルドカードであるため、ブーリアン型の Debug の参照を接続すると、オプションは False と True のオプションに変わります。
Falseに「None」を設定し True を For Duration に設定します。
ブループリント関数を保存してコンパイルします。
このロジックは Debug 変数を使用して、ライン トレースのデバッグ描画がアクティブかどうかを判断します。 デバッグ変数が false の場合、デバッグ モードはなしに設定され、デバッグ描画はレンダリングされません。 デバッグ変数が「true」に設定されていると、Select ノードによって For Duration デバッグ描画が有効になり、ランタイム時にライン トレースがアクティブである間、レンダリングされます。 必要に応じて、1 つのフレームのみライン トレースを描画する For One Frame や、プロジェクトが実行されている限りデバッグ描画をアクティブなままにする Persistent (永続) など、他のオプションを使用することができます。 このインスタンスでは、デバッグ時にライン トレースを描画するのに最も便利な方法は、For Duration です。
敵がそのプレイヤーを追跡するようにする
距離と視線を考慮しながらプレイヤーを検索する機能を呼び出せるようになったので、プレイヤーを探して追跡するロジックを敵に追加できました。
次の手順を実行します。
コンテンツ ブラウザで「Content」>「AdventureGame」>「Designer」>「Blueprints」>「キャラクター」に移動し、「BP_Enemy」を開きます。
イベント グラフで、Event Tick ノードの実行ピンをドラッグし、Branch ノードを作成します。 注:ゲームのプレイ中に各フレームで On ティック イベントが実行されます。 敵が常にプレイヤーの位置をチェックし、追跡を開始するかどうかを判断するようにするために使用します。
Branch ノードの条件ピンをドラッグし、ブール値の逆数を返す NOT Boolean ノードを作成します。 この場合、Eliminated 変数を反転する必要があるため、NOT ブーリアン ノードのピンをドラッグし、「Get Eliminated」を検索します。
敵が撃破されていないかチェックされ、その場合は Branch ノードの True ピンで続行されます。
Branch ノードの True ピンをドラッグし、FnBPLFind Player ノードを作成します。 このノードは、ワールド内のプレイヤーを見つけるライントレースを実行し、敵とプレイヤーの現在の距離をチェックします。
Fn BPLFind プレイヤー ノードで、そのピンを使用して次のように接続します。
プレイヤー参照:PlayerRef 変数への参照を接続します。
開始位置:[ターゲット] プロパティを [Self] に設定した Get Actor Location ノードを作成します。 これにより、ライントレースの開始位置がワールド内の敵の位置に割り当てられ続けます。
Max Detection Distance:[Promote to Variable (変数へ昇格)] を選択し、目のアイコンをクリックして編集可能にし、[Category (カテゴリ)] を [Setup (設定)] に変更します。 ブループリントをコンパイルした後、[Default Value (デフォルト値)] を「20000」(200 メートル) に設定します。 この値が小さいほど、プレイヤーは敵にプレイヤーを検知させるために近くにいる必要があります。
デバッグ:[Promote to variable (変数への昇格)]を選択し、DebugDetectionと呼び出します。 また、この変数を編集可能に設定し、[Setup (設定)] カテゴリに表示します。
プレイヤーがライントレースによって見つかった場合は、敵の最大移動速度を適切な速度に設定し、敵をプレイヤーに向かって移動させることをお勧めします。 有効でない場合は、速度を 0 に設定し、敵がプレイヤーに向かって移動できないようにします。
FnBPLFindPlayer ノードで、[Found (見つかった)] ピンを右クリックして、変数に昇格します。 これで、その新しい変数に対する Set ノードが自動的に作成されます。 ノードの実行ピンも接続します。これで、見つかった結果をグラフ内の別の場所で使用することができます。
Set ノードの後に、Branch ノードを接続します。 Branch ノードの Condition ピンを Set Found ノードの出力ピンにドラッグします。
[コンポーネント] パネルで、キャラクター Movement (CharMoveComp) をイベント グラフにドラッグします。 そのピンをドラッグして、Set Max Walk Speed ノードを作成します。
Branch ノードの True ピンをドラッグし、Set Max Walk Speed ノードに接続します。
[Variables (変数)] パネルから Max Speed 変数をイベント グラフにドラッグし、[Get] を選択して、Set ノードの Max Walk Speed ピンに接続します。
次に、Set Max Walk Speed ノードとCharacter Movement ノードを複製します。 Branch ノードの False ピンを新しい Set ノードに接続します。
Max Walk Speed プロパティを「0」に設定します。
これにより、敵は、その AI MoveTo タスクをキャンセルせずに移動を停止し、タスクを再度実行する必要があります。
Branch ノードの「True」ピンに接続した Set ノードの後に、MoveToPlayer ノードを接続して、このイベントを呼び出し、プレイヤーを見つけた場合のみに敵が動くようにします。
これで、敵がフレームごとにプレイヤーを探すようになったので、イベント BeginPlay ロジックの最後に追加した Move to Player ノードを削除します。 このノードは、完成途中の敵をテストするのに役立ちましたが、必要はありません。
MoveToPlayer のイベント ロジックに移動します。 次に、プレイヤーが見つかった場合にのみ、敵にこのイベントを実行させるようにします。
イベントノードと AI Move To の間のワイヤーを削除します。 Branch ノードの True ピンを使用して、これら 2 つのノードの間に Branch ノードを接続します。
Branch の条件として Found 変数への参照を追加します。
プレイヤーが敵との指定された距離内にいて、2 つの間に障害物がない場合、敵の移動速度は MaxSpeed 変数に設定され、MoveToPlayer ロジックが実行されます。 これらの条件のいずれかが満たされていない場合、敵の移動速度は 0 に設定され、敵がプレイヤーに向かって移動するのをブロックします。
敵がダメージを受けることを許可
このブループリントをまとめる前に、敵もダメージを受けることができるようにする必要があります。 次の手順を実行します。
イベント グラフ内の任意の場所を右クリックして Event AnyDamage ノードを作成します。
CurrentHP 変数をイベント グラフにドラッグして、Set CurrentHP を選択します。
与えたダメージを CurrentHP から減算します。 まず、イベント AnyDamage の実行ピンをドラッグして、Set ノードに接続します。
Current HP プロパティのピンをドラッグして、Subtract ノードを作成します。
Subtract ノードの下のピンをドラッグし、Event AnyDamage ノードの Damage プロパティに接続します。
次に、Subtract ノードの上のピンをドラッグして Get Current HP ノードを作成します。
そのため、このアクタにダメージが与えられると、これは CurrentHP 変数の値を受け取り、その値からダメージを減算してから、CurrentHP の値を新しい値に設定します。
次に、CurrentHP が 0 以下の値であるかどうかを確認します。そうすると敵がキルされます。
SET ノードのピンをドラッグし、新しい Branch ノードを作成します。
Branch ノードの Condition ピンをドラッグして、Less Equal (<=) ノードを作成します。
上のピンをドラッグして、新しい Get CurrentHP ノードを作成します。 下側のピンのプロパティが「0」に設定されていることを確認してください。
Branch ノードの True ピンからドラッグし、Do Once ノードを作成します。 その [完了] ピンをドラッグして、Set Eliminated ノードを作成します。
Set ノードで、Eliminated プロパティを true に切り替えます。
Set ノードの後に、Duration が 2 に設定されているディレイ ノードを接続します。
最後に、Delay ノードの [Completed] ピンをドラッグして、Target プロパティを「self」に設定した Destroy Actor ノードを作成します。
必ずブループリントを保存してコンパイルします。
敵のナビゲーションに NavMesh を作成する
敵をレベルに追加してプレイヤーを追跡させる前に、Enemy AI がレベルを移動するために使用する NavMesh をビルドする必要があります。
NavMesh は「Navigation Mesh (ナビゲーション メッシュ)」の略で、AI がナビゲートできるレベル上の領域を定義するために使用できます。 このチュートリアルで NavMesh を作成することで、敵がプレイヤーを追うために移動できるゾーンを定義します。
BP_Enemy ブループリント エディタを閉じて、Unreal Engine のレベル エディタに移動します。 メイン ツールバーで [Add (追加)] ボタンをクリックし、[Volumes (ボリューム)] に移動して Nav Mesh Bounds Volume (ナビメッシュ バウンズ ボリューム) を作成します。 これにより、プロジェクトで AI にナビゲート可能なゾーンを割り当てるために使用できるオブジェクトが作成されます。
緑色のゾーンが表示されない場合は、キーボードの P キーを押してデバッグ ビューに切り替えます。 これを使用すると、レベル ビューポートで NavMesh の詳細 (レベル上のナビゲート可能なゾーン、レベル ビューポートの左側のテキストベースのデバッグ情報など) を表示することができます。
トランスフォーム ツールを使用すると、NavMesh の移動やスケール (キーボードの W および R キー) を行って、NavMesh のバウンドを変更することができます。 このゾーンは好みに合わせてスケールできます。 この場合、NavMeshBoundsVolume オブジェクトを選択し、[詳細パネル] の [トランスフォーム] セクションの [X]、[Y]、[Z] のフィールドの値を 6、7、1 にスケールします。
NavMesh をスケールおよび移動すると、キューブのような障害物とみなされるオブジェクトを含まない場合は、バウンディング ボックスのサイズに合わせて緑色のゾーンが拡大します。
赤で切り取られている部分は、ゲーム内で AI がナビゲートできないことを意味しています。
ヒント:Unreal エディタによって NavMesh に含まれていない要素が含まれている場合は、そのメッシュ レベル オブジェクトを選択し、詳細パネルの [Can Ever Affect Navigation (ナビゲーションへの影響が許可)] を無効にします。
デバッグ情報に「NavMesh Needs To Be Rebuilt (NavMesh は再ビルドが必要です)」というメッセージが表示された場合は、メニュー バーの [Build (ビルド)] に移動し、[Build Paths (ビルド パス)] を選択します。 これにより、NavMeshがリビルドされます
レベルに敵を追加する
敵キャラクター用の NavMesh 領域を作成して定義した後、レベルに追加することができます。
コンテンツ ブラウザを開き、敵のブループリントの場所に移動します。 Enemy ブループリントをレベル ビューポートにドラッグし、プレイヤーの前に配置します。 両方が NavMesh のバウンド内にあることを確認します。つまり、緑色のゾーン上にあります。
レベルのビューポートまたはアウトライナー パネルで Enemy アクタを選択する。 詳細パネルでは、ブループリントに追加した変数が Default および Setup プロパティ セクションに表示されます。 これらの値はプロジェクトのニーズに合わせて変更することができます。また、デバッグ検出変数をオンにしてライン トレースのデバッグ描画を有効にすることもできます。
この時点でゲームをプレイすると、敵とプレイヤーの距離によっては敵は動いていないことがあります。 敵に近づくと、敵がプレイヤーの追跡を開始します。
障害物を使ってみましょう。 プレイ モードを終了し、メイン ツールバーの [Add (追加)] ボタンを押して [Shapes (形状)] > [Cube (キューブ)] を選択することで、緑色のゾーンの中央にキューブを追加します。 これにより、キューブが自動的に障害物であると見なされて、カットオフが実行されます。
プレイヤーがこのキューブの背後にいる場合、ライントレースはキューブで遮られるため敵はプレイヤーを追跡できず、結果としてプレイヤーを見つけることができません。 プレイヤーがキューブの周りを歩き、敵がプレイヤーを直視した場合、敵はプレイヤーを追跡し続けます。
意図した通りに動かない場合は、ブループリントで作成した変数に、シーンの BP_Enemy で設定された値が正しいかどうかをダブルチェックしてください。 最大速度または最大検出距離の値を設定しない場合、敵 AI は動きません。 値が小さすぎる場合も 同じことが起こることがあります。
プロジェクト内の敵の位置をデザインする
このサンプル レベルでは、Hallway 3 と Room 3 に複数の敵を配置しました。 最初の敵はホールウェイ 3 に 1 つ配置されました。これは、プレイヤーが敵キャラクターとその能力について学び、精通するためのシンプルな最初の遭遇を与えるために行われました。
廊下で 1 体の敵に遭遇した後、ルーム 3 に 2 つの敵キャラクターを配置し、プレイヤーにさらなる挑戦を用意しました。 敵の数とバリエーションを使用して、プロジェクト全体に異なるレベルの難易度を設定することができます。 プレイヤーを新しい敵や課題に徐々に導いていくことで、よりバランスの取れた感覚の難易度カーブを作成し、プレイヤーが時間の経過とともにこのゲームに慣れることができます。 困難な敵との遭遇を作成することで、プレイヤーにナビゲーションの方法や敵を倒す方法を学んだ後に、プレイヤーにやりがいのある課題を提供することができます。
次の内容
次のモジュールでは、プレイヤーがより速い移動速度で空間や課題を乗り越えるためのダッシュ メカニックを作成する方法について学習します。 これは、空間を移動する際にプレイヤーがより効率的に感じられるようにすると同時に、プロジェクトに追加した敵を避けるためのツールをプレイヤーに提供するために使用できます。
プレイヤーにスプリント メカニックを追加する
入力アクションを使用して、プレイヤー キャラクターの移動セットにスプリント メカニックを追加します。