
一人称シューティングゲーム(FPS)は、プレイヤーが武器を使用して、キャラクターの目を通して世界を見るジャンルです。 Call of DutyやBattlefieldなどのフランチャイズの成功に見られるように、FPSゲームは非常に人気があります。
Unreal Engineは元々FPSの開発用に作成されたため、このようなゲームを作成するためにそれを使用することは論理的です。 このチュートリアルでは、次のことを学びます。
- 移動して見回すことができる一人称視点からポーンを作成する
- 武器を作成し、プレイヤーのポーンに結び付けます
- 行追跡(光線追跡とも呼ばれます)を使用して弾丸を撃ちます
- 俳優にダメージを与える
注:この記事は、Unreal Engineに関する一連のチュートリアルの第10部です。
- パート1:エンジンの紹介
- パート2:ブループリント
- パート3:材料
- パート4:UI
- パート5:簡単なゲームを作成する方法
- パート6:アニメーション
- パート7:サウンド
- パート8:パーティクルシステム
- パート9:人工知能
- パート10:シンプルなFPSを作成する方法
仕事を始める
空白のプロジェクトをダウンロードして解凍します。 プロジェクトフォルダーに移動し、 BlockBreaker.uprojectを開きます 。 次のシーンが表示されます。

緑の壁には多くの目標があります。 破損すると、赤に変わります。 彼らの健康がゼロに達すると、彼らは消えます。 赤いボタンはすべての目標をリセットします。
まず、Pawnプレーヤーを作成する必要があります。
ポーンプレーヤーの作成
Blueprintsフォルダーに移動して、新しいBlueprint Classを作成します。 親クラスとしてCharacterを選択し、 BP_Playerという名前を付けます。

CharacterはPawnのバリエーションですが、 CharacterMovementコンポーネントなどの追加機能を備えています。

このコンポーネントは、ウォーキングやジャンプなどの動きを自動的に処理します。 Pawnが移動するように、対応する関数を呼び出すだけです。 このコンポーネントでは、歩行速度やジャンプ速度などの変数も設定できます。
Pawnを移動するには、プレイヤーがいつ移動キーを押したかを知る必要があります。 これを行うために、キーW 、 A 、 S 、およびDに動きを割り当てます。
注:バインディングに慣れていない場合は、 ブループリントに関するチュートリアルの一部でバインディングについて読むことができます。 キーバインディングにより、どのキーがアクションを実行するかを決定します。
モーションスナップの作成
[ 編集] - [プロジェクト設定]を選択し、 入力設定を開きます。
MoveForwardおよびMoveRightという2つの軸マッピングを作成します。 MoveForwardは前後に駆動します。 MoveRight-左右に移動します。

MoveForwardの場合 、キーをWに置き換えます。 その後、別のキーを作成してSを選択します。 Sの スケールを-1.0に変更します。

注: [ スケール]フィールドの詳細については、 ブループリントに関するチュートリアルの一部をお読みください。 「 軸の値と入力スケール 」セクションでは、それが何であり、どのように使用するかを説明しています。
後で、スケール値に前方ポーンベクトルを乗算します。 これにより、 正のスケールで前方ベクトルが得られます。 スケールが負の場合、ベクトルは後方に向けられます 。 結果のベクトルを使用して、Pawnを前後に移動できます。

ここで、左右に移動する場合も同じようにする必要があります。 MoveRightのキーをDに変更します。 次に、新しいキーを作成して、Aを選択します。 Aの スケールを-1.0に変更します。

バインディングを設定したら、移動に使用する必要があります。
モーション実装
BP_Playerを開き、イベントグラフを開きます。 MoveForwardイベント( Axis Eventsリストにリストされているもの)を追加します。 このイベントは、何もクリックしなくても、すべてのフレームで実行されます。

また、以前に設定されたスケール値に等しい軸値も出力します。 Wを押すと出力1に 、 Sを押すと-1に適用されます。 キーを押さないと、出力は0になります 。
次に、Pawnが移動するように注文する必要があります。 追加移動入力を追加し、次のように接続します。

運動入力の追加はベクトルを受け取り、それにスケール値を掛けます。 これにより、適切な方向に変換されます。 Characterを使用しているため、 CharacterMovementコンポーネントはPawnをその方向に移動します。
次に、移動の方向を示す必要があります。 前に進みたいので、 Get Actor Forward Vectorを使用できます。 これにより、前方ベクトルが返されます。 次のように作成して接続します。

要約すると:
- MoveForwardは各フレームを実行し、 軸の値を出力に渡します。 Wを押すとこの値は1になり、 Sを押すと-1になります。 これらのキーのいずれも押さない場合、出力は0になります 。
- 移動入力の追加 は、前方のポーンベクトルにスケール値を乗算します。 このため、押されたキーに応じて、ベクトルは前方または後方に向けられます。 キーを押さない場合、ベクトルには方向がありません。つまり、ポーンは移動しません。
- CharacterMovementコンポーネントは、 Add Movement Inputから結果を取得し、Pawnをその方向に移動します。
MoveRightのプロセスを繰り返しますが、 Get Actor Forward VectorをGet Actor Right Vectorに置き換えます。

動きを確認するには、ゲームモードでデフォルトでポーンを設定する必要があります。
Pawnをデフォルトとして設定
[ コンパイル]をクリックして、メインエディターに戻ります。 [ ワールド設定]パネルを開き、 [ ゲームモード]セクションを見つけます。 デフォルトのポーンクラスの値をBP_Playerに変更します 。

注: [ワールド設定]パネルがない場合は、ツールバーに移動して[ 設定] \ [ワールド設定]を選択します。
ゲームを開始すると、 BP_Playerが自動的に使用されます 。 Playを押し、キーW 、 A 、 SおよびDを使用してレベルを移動します。
GIF

次に、頭を回すためのバインディングを作成します。
概要バインディングを作成する
プロジェクト設定を開きます。 LookHorizontalおよびLookVerticalという2つの軸マッピングを作成します。

LookHorizontalのキーをMouse Xに置き換えます。

このバインディングは、マウスを右に動かすと正の値を生成し、逆も同様です。
LookVerticalのキーをMouse Yに変更します。

このバインディングは、マウスを上に動かすと正の値を生成し、逆も同様です。
次に、見回すためのロジックを作成する必要があります。
実装レビュー
Pawnにカメラコンポーネントがない場合、Unrealは自動的にカメラを作成します。 デフォルトでは、カメラはコントローラーの回転を使用します。
注:コントローラーについて詳しく知りたい場合は、 人工知能のチュートリアルをご覧ください。
コントローラーは物理的ではないという事実にもかかわらず、コントローラーにはまだ順番があります。 これは、ポーンの目とカメラを異なる方向に向けることができることを意味します。 たとえば、三人称ゲームでは、キャラクターとカメラが常に同じ方向を向いているとは限りません。
GIF

ゲーム内で最初の人からカメラを回転させるには、コントローラーの回転を変更するだけで十分です。
BP_Playerを開き、 LookHorizontalイベントを作成します。

カメラを左または右に回転させるには、 ヨーを調整する必要があります。 コントローラーヨー入力の追加を作成し、次のように接続します。

これで、マウスが水平に移動すると、コントローラーが左または右に回転します。 カメラはコントローラーの回転を使用するため、回転します。
LookVerticalのプロセスを繰り返しますが、 Add Controller Yaw InputをAdd Controller Pitch Inputに置き換えます 。

ここでゲームを開始すると、カメラの垂直方向の動きが反転していることがわかります。 これは、マウスを上に動かすと、カメラが下に見えることを意味します。
非反転制御が必要な場合は、 Axis Valueに-1を掛けます。 これにより、 Axis Valueが反転し、コントローラーの傾斜が反転します。

[ コンパイル ]をクリックし、[ 再生 ]をクリックします。 マウスで見て回ってください。
GIF

すべての動きと可視性の準備ができたので、次は武器を作成しましょう!
武器作成
ブループリントクラスを作成するときに、親クラスを選択できることを覚えていますか? 独自のブループリントを親として選択することもできます。 これは、共通の機能または属性を共有するさまざまなタイプのオブジェクトがある場合に役立ちます。
さまざまな種類の車を作成する必要があるとしましょう。 速度や色などの変数を含むベースカークラスを作成できます。 次に、車の基本クラスを親として使用するクラス(子)を作成できます。 各子クラスには同じ変数が含まれます。 これで、さまざまな速度と色のマシンを簡単に作成できます。

同じ方法で、武器を作成できます。 これを行うには、最初に基本クラスを作成する必要があります。
基本武器クラスの作成
メインエディタに戻り、タイプActorの ブループリントクラスを作成します。 BP_BaseGunと名前を付けて開きます。
次に、武器のプロパティを定義する変数をいくつか作成します。 float型の次の変数を作成します。
- MaxBulletDistance:各弾丸の最大範囲
- 損傷:弾丸が俳優に当たったときに与える弾丸の量
- FireRate:武器によって発射されたショット間のギャップ(秒単位)

注:デフォルトでは、すべての変数の値はゼロです。これはチュートリアルに非常に適しています。 ただし、新しい武器クラスに異なるデフォルト値を設定する場合は、 BP_BaseGunで設定する必要があります。
次に、この武器の物理的な表現が必要です。 Static Meshコンポーネントを追加し、 GunMeshという名前を付けます。

今のところ静的メッシュを選択する心配はありません。 これについては、子武器クラスを作成する次のセクションで扱います。
子武器クラスを作成する
[ コンパイル]をクリックして、メインエディターに戻ります。 子クラスを作成するには、 BP_BaseGunを右クリックし 、 「 子ブループリントクラスの作成 」を選択します 。
GIF

BP_Rifleという名前を付けて開きます。 クラスのデフォルトを開き、変数を次の値に設定します。
- MaxBulletDistance: 5000
- ダメージ: 2
- 発射速度: 0.1

つまり、各弾丸の最大パスは5000になります。 彼女が俳優になった場合、彼女は2ポイントのダメージを与えます。 バーストを発射するとき、各ショットの前の間隔は少なくとも0.1秒です。
次に、武器で使用されるメッシュを指定する必要があります。 GunMeshコンポーネントを選択し、 静的メッシュの値をSM_Rifleに設定します 。

これで武器の準備ができました。 [ コンパイル]をクリックし、 BP_Rifleを閉じます 。
次に、独自のカメラコンポーネントを作成します。 カメラの位置をより便利に制御できます。 また、武器をカメラに取り付けて、常にカメラの前にくるようにすることもできます。
カメラ作成
BP_Playerを開き、 カメラコンポーネントを作成します。 FpsCameraという名前を付けます。

デフォルトの位置は非常に低いため、プレーヤーは小さく感じるかもしれません。 FpsCameraカメラの場所を( 0、0、90)に変更します 。

デフォルトでは、カメラコンポーネントはコントローラーの回転を使用しません。 これを修正するには、[詳細]パネルに移動し、[ カメラ設定] \ [ポーンコントロールの回転を使用]をオンにします。

次に、武器を配置する場所を設定する必要があります。
武器の場所
武器の場所を作成するには、 Sceneコンポーネントを使用できます。 これらのコンポーネントは、変換のみを含むため、場所の設定に最適です。 FpsCameraを選択し、 Sceneコンポーネントを作成します。 したがって、カメラに接続されます。 GunLocationという名前を付けます。

GunLocationをFpsCameraにアタッチしたため、武器は常にカメラに対する位置を維持します。 したがって、カメラの前に武器が常に表示されます。
次に、 GunLocationコンポーネントの場所を( 30、14 、-12)に設定します。 そのため、武器をカメラの前に少し横に置きます。

次に、 回転値(0、0、-95)を設定します。 武器を取り付けると、常に画面の中央に向けられているように見えます。

次に、武器を作成してGunLocationにアタッチする必要があります。
武器の作成と取り付け
イベントBeginPlayを見つけて、 Spawn Actor from Classを作成します。 ClassをBP_Rifleに設定します 。

後で武器を使用する必要があるため、変数に格納します。 タイプBP_BaseGunの変数を作成し、 EquippedGunという名前を付けます。
重要なのは、変数がBP_Rifle型ではないことです。プレーヤーは、1つだけでなく、さまざまな種類の武器を持つことができるからです。 別のタイプの武器を作成すると、 BP_Rifleタイプの変数に保存できなくなります。 これは、長方形の穴に円を入れようとするようなものです。
変数のBP_BaseGunタイプを選択して、多くの「形状」に適合する大きな「穴」を作成しました。
EquippedGunをReturn Value Spawn Actor From Classに設定します。

武器を取り付けるには、 AttachToComponentを使用できます。 それを作成し、 ロケーションルールとローテーションルール を[ターゲットにスナップ]に設定します 。 これにより、武器の位置と回転は親と同じになります。

次に、 GunLocationへのリンクを作成し、次のようにすべてを接続します。

要約すると:
- BP_Playerを作成すると、 BP_Rifleのインスタンスが作成されます
- EquippedGunは、今後の参照のために、作成されたBP_Rifleへのリンクを保存します。
- AttachToComponentは武器をGunLocationに接続します
[ コンパイル ]をクリックし、[ 再生 ]をクリックします。 プレイヤーを作成すると、武器も作成されます! コーナリング中、武器は常にカメラの前になります。

今から楽しみが始まります:撮影します! 行頭文字がどこかにヒットしたかどうかを確認するには、ライントレースを使用できます。
弾丸射撃
トレースラインは、開始ポイントと終了ポイントを受け取る(ラインを形成する)関数です。 彼女は何かにつまずくまで、最初から最後まで直線で各ポイントをチェックします。 弾丸のヒットをチェックするゲームでは、この方法が最もよく使用されます。
射撃は武器の機能であるため、プレイヤーではなく武器のクラスで実行する必要があります。 BP_BaseGunを開き、 撮影機能を作成します。
次に、2つのベクター入力を作成し、それらにStartLocationおよびEndLocationという名前を付けます。 これらは、トレース行の開始点と終了点になります( BP_Playerから渡します )。

LineTraceByChannelを使用して行トレースを実行できます。 このノードは、 可視性またはカメラのコリジョンチャネルを使用してヒットをチェックします。 次のように作成して接続します。

ここで、行のトレースが何かに入っているかどうかを確認する必要があります。 ブランチを作成し、次のように接続します。

ヒットすると、 戻り値はtrueを出力し、その逆も同様です。
弾丸が当たった場所に関する視覚的なフィードバックをプレーヤーに与えるには、パーティクルエフェクトを使用できます。
バレットヒットパーティクルの作成
まず、ヒットトレースの場所を取得する必要があります。 グラフ上でOut Hitを左クリックします 。 メニューからBreak Hit Resultを選択します。

したがって、直接トレース結果に関連するさまざまな連絡先を持つノードを作成します。
ロケーションでスポーンエミッタを作成し、 エミッタテンプレートをPS_BulletImpactに設定します 。 次に、その場所をBreak Hit Resultノードの場所に接続します。

これがどのように見えるかです:

要約すると:
- シュートを実行すると、送信された開始点と終了点で線をトレースします
- ヒットが修正されると、 Spawn Emitter at LocationはヒットポイントでPS_BulletImpactを作成します。
シューティングロジックが完成したので、それを使用する必要があります。
関数呼び出しを撮影する
まず、撮影用のキーバインドを作成する必要があります。 [ コンパイル ]をクリックして、[ プロジェクト設定]を開きます。 Shootという新しいAxis Mappingを作成します。 左マウスボタンを選択して、 プロジェクト設定を閉じます。

次に、 BP_Playerを開いて、 シュートイベントを作成します。

プレーヤーがシュートキーを押したかどうかを確認するには、 軸の値が1( 1 )に等しいかどうかを確認するだけです。 選択したノードを作成します。

次に、 EquippedGunへのリンクを作成し、そのシュート機能を呼び出します。

次に、ラインをトレースするための開始点と終了点を計算する必要があります。
直線トレースポイントの計算
多くのFPSでは、弾丸は武器からではなく、カメラから飛び出します。 これは、カメラが既にスコープと完全に整合しているためです。 したがって、カメラから撮影すると、弾丸はカーソルのある場所に飛ぶことが保証されます。
注:一部のゲームはまだ銃撃戦を実装しています。 ただし、正確に一目で撮影するには、追加の計算が必要です。
FpsCameraへのリンクを作成し、それをGetWorldLocationに接続します 。

次に、エンドポイントが必要です。 武器にMaxBulletDistance変数があることを忘れないでください。 これは、エンドポイントがカメラからMaxBulletDistanceユニットの距離にある必要があることを意味します。 これを実装するには、専用ノードを作成します。

次に、すべてを次のように接続します。

要約すると:
- プレイヤーがマウスの左ボタンを押したままにすると、武器はカメラの開始点で弾丸を放出します
- 弾丸はMaxBulletDistanceで指定された距離を飛行します
[ コンパイル]をクリックしてから[ 再生]をクリックします。 マウスの左ボタンを押したまま 、撮影を開始します。
GIF

武器はすべてのフレームで撃ちますが。 これは速すぎるため、次のステップでは、武器の発射頻度を減らします。
発火率の低下
まず、プレイヤーがシュートできるかどうかを判断する変数が必要です。 BP_Playerを開き、 CanShootというブール変数を作成します。 デフォルトでtrueに設定します。 CanShootがtrueの場合、プレーヤーは射撃でき、その逆も可能です。
Branchセクションを次のものに置き換えます。

プレイヤーは、 シュートキーが押され、 CanShoot変数がtrueの場合にのみシュートできます 。
選択したノードを追加します:
変更点:
- プレーヤーは、 左マウスボタンを押したまま 、 CanShootがtrueの場合にのみ撮影できます。
- プレーヤーが弾丸を発射すると、 CanShoot変数はfalseに 設定されます 。 これにより、プレーヤーは再び撮影できなくなります。
- FireRateで指定された間隔の後、 CanShootは再びtrueに設定されます。
[ コンパイル]をクリックし、 BP_Playerを閉じます 。 [ 再生]をクリックして、新しい発砲率を確認します。
GIF

ここで、ターゲットと弾丸に応答するボタンを教えます。 これは、それらにダメージを追加することで実行できます。
ダメージを与える
Unrealのすべてのアクターはダメージを受ける能力を持っています。 ただし、アクターがどのように反応するかは自分で選択できます。
たとえば、戦闘キャラクターはダメージを受けると体力を失います。 ただし、バルーンなどの一部のオブジェクトは正常ではない場合があります。 次に、ダメージを受けたときに爆発するようにボールをプログラムできます。
ダメージを受けるアクターを制御できるようにするために、まずダメージを適用する必要があります。 BP_BaseGunを開き、 シュート機能の最後にダメージの適用を追加します。

次に、どのアクタにダメージを与えるかを示す必要があります。 私たちの場合、これは直接トレースが該当するアクターです。 破損したアクタを、 ブレークヒット結果ノードのヒットアクタに接続します。

最後に、行われた損傷の量を示す必要があります。 Damageへのリンクを取得し、 Base Damageに接続します。

今、あなたがシュートを呼ぶとき、それは直接の痕跡に陥る俳優にダメージを与えます。 [ コンパイル]をクリックし、 BP_BaseGunを閉じます 。
次に、アクターがどのようにダメージを受けるかを処理する必要があります。
ダメージ処理
まず、ターゲットがどのようにダメージを受けるかを処理します。 BP_Targetを開き、 イベント AnyDamageを作成します。 このイベントは、アクターがゼロ以外のダメージを受けたときに発生します。

TakeDamage関数を呼び出して、 損傷ピンを接続します。 これにより、ターゲットのHealth変数からヘルスが差し引かれ、ターゲットの色が更新されます。

ターゲットがダメージを受けると、ヘルスを失います。 [ コンパイル]をクリックし、 BP_Targetを閉じます 。
次に、ボタンがどのようにダメージを受けるかを処理する必要があります。 BP_ResetButtonを開き、 イベント AnyDamageを作成します。 次に、 ResetTargets関数を呼び出します。

これにより、ボタンが押されたときにすべてのターゲットが復元されます。 [ コンパイル]をクリックし、 BP_ResetButtonを閉じます 。
[ 再生]をクリックして、ターゲットでの撮影を開始します。 目標を回復したい場合は、ボタンを押してください。
GIF

次はどこに行きますか?
完成したプロジェクトはここからダウンロードできます 。
このチュートリアルで作成されるFPSは非常に単純ですが、簡単に拡張できます。 さまざまな種類の射撃頻度とダメージで、より多くの武器を作成してみてください。 リロード機能を追加することもできます!