環境ハザードは、ゲームプレイを形成するうえで大きな役割を果たします。 危険や罠を使用することで、プレイヤーに結果を追加し、パズルやレベルでプレイヤーが進むにつれて難易度や緊張感を高めます。
このチュートリアル シリーズでは、プレイヤーにダメージを与えるスパイク トラップとファイア トラップを作成します。 次に、ファイア トラップ とスイッチ ゲームプレイ オブジェクトを接続し、新しいゲームプレイのメカニックとパズルを作成します。
これでプレイヤーがダメージを受けてヘルスをすべて失うことができるようになったので、ゲームを終了して再起動する失敗条件も設定し、プレイヤーに再挑戦の機会を提供したいと思います。
開始する前に
「パズル アドベンチャーの設計」の以前のセクションで取り上げた、これらのトピックを理解できていることを確認します。
変数、関数、イベント グラフなど、ブループリントの基本を説明し、ノードを追加します。
ブループリント インターフェース イベントを使用して、スイッチを別のゲームプレイ オブジェクトに切り替えます。
キーの作成 と パズル:スイッチとキューブが必要になります。
M_BasicColorマテリアルとM_BasicColor_Redマテリアル インスタンスBPI Interactionブループリント インターフェースBP_Switchブループリントクラス
関連するブループリント クラスのセットをビルドする
このチュートリアル シリーズを通して、親子関係と継承を使用する Unreal Engine アセットを紹介してきました。 継承とは、既存の親クラスの機能を再利用したり拡張したりする新しい子クラスを作成することを指します。 子クラスは、親クラスを変更することなく、それらの機能から拡張できます。 継承により、多くのアセットで便利な機能を再利用できるため、時間を節約できます。これにより、新しいアセットごとに手動で追加する必要がありません。
マテリアル インスタンス アセットは親マテリアルの機能を継承します。 多くのブループリントでは、親コンポーネントからトランスフォーム データを継承するコンポーネントを作成しました。
ゲームにはさまざまな型のハザードが登場しますが、多くの場合、同じ主要な特徴を共有しています。 親トラップのブループリントでそのような共有機能を定義でき、それぞれの子トラップのブループリントでそれらの機能を拡張して、異なるビジュアルと動作を追加できます。
ベース (親) トラップは、プレイヤーのオーバーラップを検出し、ダメージ ゲームのメカニックを使用して、時間の経過とともにプレイヤーのヘルス値を減らす必要があります。 次に、子トラップを作成 (またはサブクラス化) して、ベース トラップの機能を拡張し、ビジュアルや動作を追加します。 スパイク トラップは外観にスタティック メッシュを追加し、ファイア トラップは、炎のエフェクトと動作を追加して、オンとオフを切り替えます。
レベルはまだブロックアウトの段階であるため、将来のビジュアル デザインに役立つように、それぞれのトラップの単純化されたバージョンを作成することに注力します。
ベース トラップのブループリントを作成する
まず、特殊なトラップの親および基礎として、ベース トラップのブループリント クラスを作成します。
トラップの共通機能を定義するブループリントを作成するには、次の手順を実行します。
コンテンツ ブラウザで、「Content」>「AdventureGame」>「Designer」>「Blueprints」フォルダに移動し、
「Traps」という名前の新しいフォルダを作成します。「Traps」フォルダで右クリック、または [Add (追加) ] をクリックして、新しい ブループリント クラスを作成します。
[Pick Parent Class (親クラスを選択)]ウィンドウで [Actor (アクタ)] をクリックします.このクラスに
BP_TrapBaseという名前を付けてから開きます。
コンポーネントを追加
ベース トラップには、トラップの境界を示すブロックアウト スタイルのスタティック メッシュを作成します。 すべてのトラップには、プレイヤーがいつ上ったのかを把握するためのコリジョン ボリュームも必要です。
ベース トラップの物理コンポーネントを作成するには、次の手順に従います。
[Components (コンポーネント)] タブで、[Add (追加)] をクリックし、Cube スタティック メッシュ形状を検索して追加します。
メッシュコンポーネントを
TrapBaseという名前にします。[Details (詳細)] パネルの [Transform (トランスフォーム)] で、キューブの [Scale (スケール)] を
2、2、0.1に変更し、平らな正方形の基盤を作成します。[Components (コンポーネント)] タブで、TrapBase を選択した状態で Add をクリックし、Box Collision コンポーネントを検索して選択します。
コリジョンコンポーネントを
TrapTriggerという名前にします。 これは、プレイヤーがトラップの上に立っていることを検出するために使用するコリジョン ボリュームです。BP_Switchを使用する場合と同様に、コリジョン コンポーネントをメッシュにアタッチするため、トラップのサイズを変更すると、トリガー領域が自動的に調整されます。[Details (詳細)] パネルの [Transform (トランスフォーム)] で次のプロパティを変更し、ベース メッシュの上に大きなコリジョン ボックスを作成します。
[Location] を
0、0、400に設定します。[Scale] を
1.5、1.5、12に設定します。
変数を追加
すべてのトラップには、次のような編集可能なプロパティも必要です。
ハザードがアクティブか非アクティブか。
トラップがプレイヤーに与えるダメージ。
ダメージの間隔、またはヒットの時間間隔。
そして トラップには誰がそれを衝突させたかを知らせる必要があります。
共通のプロパティをベース トラップに追加するには、次の手順に従います。
[My Blueprint (マイ ブループリント)] タブで、次の変数を作成します。
変数名
型
カテゴリ
デフォルト値
Active
ブーリアン
Setup
True
BaseDamage
Float
Setup
5.0
DamageInterval
Float
Setup
1.0
変数を作成した後、ブループリントをコンパイルしてデフォルト値を追加します。
各変数の目のアイコンをクリックして目が開いた状態にし、3 つの変数すべてを編集可能かつ公開します。
「
OtherActor」という名前の変数を追加し、型を アクタ (オブジェクト参照) に変更します。
ダメージを適用する関数を作成する
トラップに基本プロパティを設定できたので、トラップの動作の作成を開始することができます。 すべてのトラップは、プレイヤーがコリジョン ボリュームにオーバーラップしたときに、一定の間隔でプレイヤーのヒット ポイント (HP) を下げる必要があります。
Unreal Engine には、ダメージの適用や受け渡しなど、よく使用される多くのゲームプレイ メカニクスのための組み込みソリューションがあります。
トラップには、ビルトインの Apply Damage 関数ノードを使用します。 ダメージ処理ロジックを整理するために、トラップが有効な場合にトラップに接触したすべてのキャラクターに Apply Damage (ダメージを適用) を呼び出す独自の関数を作成します。
プレイヤーにトラップ ダメージを適用する関数を作成するには、次の手順を実行します。
[Functions (関数)] セクションで [Add (追加)] をクリックします。 この関数に
fnApplyDamageToTargetsという名前を付け、グラフを開きます。トラップがオンでアクティブな場合にのみダメージを適用したいため、条件が Active 変数への参照 (Get) になる Branch ノードを追加します。
このチュートリアルの後の部分で、いくつかの NPC 敵を追加するため、多数のアクタが同時にトラップにいる可能性があります。 トラップが有効な場合は、トラップに接触するすべてのアクタの配列をループします。
Branch ノードの True ピンを For Each Loop ノードに接続します。
ループの配列入力で、すべてのオーバーラップするアクタの配列を作成する必要があります。 Unreal Engine ではこの処理を行い、Get Overlapping Actors (TrapTrigger) ノードを追加します。 このノードには、ターゲットとして TrapTrigger への参照が含まれています。
Get Overlapping アクタ ノードで、クラス フィルターをキャラクターに変更し、プレイヤーと NPC のキャラクターを配列に追加できるようにします。
各配列要素またはループの各イテレーションに対して、BaseDamage 変数に設定されたダメージ量を、その配列要素内のアクタに適用します。 このためには、Apply Damage ノードを Loop Body に接続します。
Apply Damage 関数は、Unreal Engine の Game Statics ライブラリにあります。 右上隅のアイコンは、関数がネットワーク ゲームで使用でき、サーバーで実行できることを意味します。
Apply Damage ノードを設定します。
Damaged Actor ピンで ループの Array Element に接続します。
Base Damage ピンには、BaseDamage 変数への参照を接続します。
6. ブループリントを保存してコンパイルします。
完全な fnApplyDamageToTarget 機能は次のようになります。
このスニペットをコピーして、プロジェクト内の対応するグラフに貼り付けると、関数の Entry ノードを Branch ノードに接続します。
ダメージを一定時間にわたって適用するタイマーを作成する
次に、トラップが一定の時間間隔でダメージ適用関数を呼び出すようにします。 これを実行するために、Unreal Engine のタイマー機能の 1 つを使用してタイマーを作成します。
このブループリントで Set Timer by Function Nameを使用します。
このノードはタイマーを作成し、関数をそのタイマーにバインドします。タイマーが切れると、ノードは関数を呼び出し、その関数内のすべてのアクションを実行します。
ゲーム開始時にタイマーを設定するには、次の手順を実行します。
BP_TrapBaseの EventGraph タブに移動します。 提供された Event ActorBeginOverlap ノードと Event Tick ノードを削除します。トラップがアクションを実行する前に、トラップがアクティブかどうかを確認する必要があります。 Event BeginPlay ノードから、条件が Active 変数への参照である Branch ノードを追加します。
Branch ノードの [True] ピンから、Set Timer by Function Name ノードを作成します。
Timer ノードを設定します。
[Time] ピンでは、DamageInterval 変数への参照を接続します。
関数名 の横にあるテキスト ボックスをクリックして、
fnApplyDamageToTargetと入力します。関数名が正しく入力されていないと、ロジックが適切に実行されません。
ループを有効にします。
Set Timer ノードは、Timer Handleと呼ばれる戻り値を出力します。これはタイマーの追跡番号やコントローラーのように機能します。 タイマーを停止、一時停止、再開するには、このタイマー ハンドルを参照するため、新しい変数に保存します。
[My Blueprint (マイ ブループリント)] パネルで新規変数を作成し
「TimerHandler」という名前を付けます。 型を Timer Handle に変更します。Set Timer Handler ノードを追加し、これを Set Timer by Event の戻り値と実行ピンに接続します。
Unreal Engine がタイマーを作成すると直ちに実行が開始されるため、キャラクターがトラップに足を踏み入れるまでタイマーを一時停止させる必要があります。 Pause Timer by Handle ノードを接続し、TimerHandler を指定します。
ブループリントを保存してコンパイルします。
Set Timer by Event ノードを使用してタイマーを作成することもできます。 ここで、ノード アクション リストを使用してカスタム イベントを追加し、アクションをタイマーにバインドするデリゲートとして使用します。
カスタム イベントは再利用可能で、関数に似た名前付きのロジック ブロックです。 機能とは異なり、ディレイ、タイムライン ノード、他の潜在的なアクションを含むことができるため、ゲームが複雑になった場合には、このメソッドを使用する必要がある場合があります。
イベントの Square デリゲート ピンに接続し、そのイベントの参照を Timer ノードに渡します。 これはイベントをトリガーするのではなく、後で (一定間隔が過ぎたとき) のためにイベントとそのアクションを格納します。
ダメージの開始と停止
ダメージ タイマーを作成して一時停止したため、準備ができて待機しています。 ここで、キャラクターがトラップのコリジョン ボリュームを踏むとダメージが再開し、キャラクターがボリュームとオーバーラップするのをやめるとダメージを一時停止するようにします。
ダメージを開始するロジックを追加するには、次の手順を実行します。
[Components] パネルで TrapTrigger コンポーネントを右クリックし、[Add Event] から [Add OnComponentBeginOverlap] を選択します。
イベントの後、Set Other Actor ノードを接続して、オーバーラップしているアクタを変数に保存します。
イベントと Set ノードの Other Actor (その他のアクタ) ピンを接続します。
fnApplyDamageToTarget ノードを接続し、キャラクターがトラップに触れた直後にダメージを受けるようにします。
Unpause Timer by Handle ノードを接続し、タイマーとダメージのインターバルを再開します。 そのHandle 入力に、TimerHandler 変数への参照を接続します。
時間の経過とともにダメージを停止するロジックを追加するには、次のステップに従います。
TrapTrigger コンポーネントを右クリックして、[Add Event] > [On Component End Overlap] を選択します。
イベントの後に、Pause Timer by Handle ノードを接続し、再度 TimerHandler への参照を指定します。
ブループリントを保存してコンパイルします。
トラップがダメージ タイマーを作成、開始、一時停止するようになりました。
完成した BP_TrapBase イベント グラフは次のようになります。
タイマーとタイマー管理の詳細については、「ゲームプレイ タイマー」を参照してください。
ベース トラップをテストする
トラップをテストするには、トラップによってダメージが適用されたときに画面上に報告する Print String メッセージを追加します。
トラップが意図したとおりに動作していることを示すメッセージを画面に出力するには、次の手順を実行します。
BP_TrapBaseで、fnApplyDamageToTarget タブに移動します。関数のグラフで、Print String ノードを Apply Damage ノードの後に接続します。
In String を
Player Hit!に変更します。Print String ノードの下の矢印をクリックして、その他のオプションを表示し、Duration を
5に変更します。 これにより、ダメージを受けた際の時間経過を確認しやすくなります。ブループリントをコンパイルして保存します。 コンテンツ ブラウザで、
BP_TrapBaseのインスタンスをレベルにドラッグします。レベルをプレイし、トラップに足を踏み入れます。 新しい「プレイヤー ヒット!」メッセージが、毎秒ごとに表示される必要があります
スパイク トラップのサブクラス
親クラスが完了したので、サブクラス化を開始します。
まず、ベース トラップの外観を変化させるスパイク トラップを作成し、形状言語を追加します。 フラットなトラップは危険そうには見えませんが、とげのあるオブジェクトはプレイヤーにダメージを与えるものと認識してしまいます。
スパイク トラップを作成するには、次の手順を実行します。
コンテンツ ブラウザ の「Traps」 フォルダで、
BP_TrapBaseを右クリックし、[Create Child Blueprint Class (子ブループリント クラスの作成)] を選択します。ブループリントクラスに
「BP_TrapSpikes」という名前を付けて開きます。[Components (コンポーネント)] タブで、DefaultSceneRoot を選択した状態で Add をクリックし、「Cone (コーン)」を検索して選択します。
コーンのサイズを変更し、それぞれ 4 つのコーンで構成される 4 行 (全部で 16 個) の行に収まるように、配置します。
コーンの [Details (詳細)] パネルの Transform (トランスフォーム) セクションで、次のプロパティを変更します。
[Location] を
「-75」、「-75」、「25」に変更します。[Scale] を
0.5、0.5、0.4に変更します。
これで ベースメッシュのコーナーに小さなスパイクができました
視覚的なコントラストを加えるには、Materials (マテリアル) セクションでドロップダウン メニューを使用して、コーンのマテリアルを
M_BasicColor_Redに変更します。コーンを選択して 3 回複製 (Ctrl + D) し、各コーンを 50 ユニット平行移動して、ベース メッシュの片側に一列に並べます。
Ctrl キーを押したままにして、4 つのコーンをすべて選択し、複製します。 コンポーネント パネルで、4 つの新しいコーン (最大数のサフィックスを持つコーン) を選択し、50 ユニット移動します。 これを 2 回繰り返して、4x4 のコーンのグリッドを作成します。
スパイクの傾斜や角度によって、プレイヤーがトラップから抜け出すのがギクシャクする場合があります。 スパイクの間にプレイヤーが着地しないように、見えない床をスパイクの上部に追加します。
[Components (コンポーネント)] タブで、TrapBase メッシュを複製し、
InvisFloorという名前を付けます。スパイクの先端のみがフロア上に見えるようにフロアを上に移動させます。
[Details (詳細)] パネルの [Collision (コリジョン)] セクションで、[Collision Presets (コリジョン プリセット)] が [BlockAllDynamic] に設定されていることを確認します。 これにより、すべてのアクタがメッシュを通過するのをブロックします。
Rendering (レンダリング) セクションで Visible(表示) をオフにします。 これにより、ビューポート内およびゲームプレイ中はメッシュが非表示になります。
[Components (コンポーネント)] タブで、TrapBase メッシュを選択します。 [Details (詳細)] パネルの [Rendering (レンダリング)] セクションで [Hidden in Game (ゲーム内で非表示)] を有効にします。 これにより、ビューポートでメッシュが表示されたままになりますが、ゲームプレイ中は非表示になるため、スパイクのみが表示されます。
ブループリントを保存してコンパイルします。
スパイク トラップのサブクラスには、ベース トラップのすべての動作が含まれるため、トラップが作動したときに「プレイヤー ヒット!」メッセージも出力します。 BP_TrapSpikes のインスタンスをレベルにドラッグし、テストします。
ファイア トラップのサブクラス
次に、ベース トラップの動作を拡張するトラップを作成します。 ファイア トラップは、プレイヤーがスイッチでオフにできるハザードを追加します。これは、新しいパズルに変えることができるゲームプレイのメカニックです。
パズル:スイッチとキューブ では、スイッチが他のゲームプレイ オブジェクトのオンとオフを切り替えるために使用できる BPI_Interaction ブループリント インターフェースを作成しました。 また、このインターフェースをトラップのブループリントで使用することで、ゲームプレイ中にスイッチがトラップの Active 変数を変更できるようにすることもできます。
まずは、トラップが無効になったときに使用する新しいマテリアルが必要です。
ファイア トラップの黒色のマテリアルを作成するには、次の手順を実行します。
コンテンツ ブラウザ で、「AdventureGame」>「Designer」>「Materials」フォルダに移動します。
「
M_BasicColor」を右クリックして [Create Material Instance (マテリアル インスタンスを作成)] を選択します。マテリアル インスタンスに
M_BasicColor_Blackという名前を付けて開きます。[Global Vector Parameter Values (グローバル ベクター パラメータ値)] を展開して、[Color (色)] を有効にし、色見本をクリックしてダーク グレー (Hex sRGB =
3D3B3BFF) に変更します。 インゲームでは、真っ黒よりもよく見えます。マテリアル インスタンスを保存して閉じます。
ファイア トラップをサブクラスにするには、次の手順を実行します。
コンテンツ ブラウザで
BP_TrapBaseを右クリックして、Create Child Blueprint Class (子ブループリント クラスの作成) を選択します。ブループリントに
「BP_TrapFire」という名前を付けて開きます。ベース メッシュの色を変更し、ファイア トラップを表現するようにします。 TrapBase コンポーネントを選択し、[Details (詳細)] パネルの [Materials (マテリアル)]セクションでマテリアルを
「M_BasicColor_Red」に変更します。ビューポートの上にある Class Settings (クラス設定) をクリックします。
[Details (詳細)] パネルの [Interfaces (インターフェース)] セクションの [Implemented Interfaces (実装されたインターフェース)] の横にある [Add (追加)] をクリックし、「
BPIInteraction」を検索して選択します。[My Blueprint] パネルの [Interfaces] セクションに、fnBPISwitchOff と fnBPISwitchOn イベント関数が表示されます。
BP_Switchと同様に、ファイア トラップのカスタマイズ可能なマテリアルを設定します。[My Blueprint (マイ ブループリント)] パネルの [Variables (変数)] セクションで、
「OffMaterial」と「OnMaterial」という名前の2 つの変数を作成します。タイプを マテリアルインターフェース (オブジェクト参照) に変更します。
目のアイコンをクリックし、公開して編集可能にします。
[Category (カテゴリ)] を [Setup (設定)] に変更します。
コンパイルし、次のデフォルト値を設定します。
OffMaterial:
M_BaseColor_BlackOnMaterial:
M_BaseColor_Red
ブループリントを保存してコンパイルし、インターフェース イベントをトラップのイベント グラフで使用できるようにします。
トラップの動作を拡張する
パズル:プラットフォームを動かすで、移動プラットフォームを作成したときと同様に、スイッチが fnBPISwitchOn と fnBPISwitchOff を呼び出したときに次のアクションを取るように、トラップのイベントグラフを設定する必要があります。
トラップを有効/無効にします。
トラップのマテリアルを変更します。
移動するプラットフォームでは、プレイヤーがスイッチを起動したときにプラットフォームが移動し始める必要がありました。 トラップについては、その逆を行う必要があります。つまり、トラップはレベルが開始したときにアクティブになり、プレイヤーがスイッチをアクティブにしたときにオフになる必要があります。
プレイヤーがスイッチを押したときにトラップを無効にするロジックを追加するには、次のステップを実行します。
Fire Trap の EventGraph タブに移動します。 [My Blueprint (マイ ブループリント)] パネルの [Interfaces (インターフェース)] リストで、fnBPIButtonOn をダブルクリックして、イベント ノードをグラフに追加します。
BP_TrapBase変数は My Blueprint (マイ ブループリント) パネルに表示されませんが、ノード アクション リストでアクセスできます。 Event fnBPISwitchOn ノードの exec ピンをドラッグし、アクティブな変数を検索し、Set Active を選択します。 [Keep Active] は無効です。Set ノードの後に、Set Material (TrapBase) ノード (アクション リストの Rendering > Material セクション) を接続します。
Set Material ノードで、OffMaterial 変数への参照を Material ピンに接続します。
スイッチが無効になった場合にファイア トラップを起動するロジックを追加するには、次の手順を実行します。
[Interfaces (インターフェース)] セクションで、Event fnBPISwitchOff をダブルクリックして、該当するノードを追加します。
イベントの後に Set Active 変数ノードを接続しますが、今度は Active を有効にします。
Set ノードの後に、Set Material (TrapBase) ノードを接続し、OnMaterial への参照を接続します。
ブループリントを保存してコンパイルします。
完全なファイア トラップ イベント グラフは次のようになります。
BP_TrapFire のインスタンスをレベルに追加し、試してみます。
プレイヤーの HP を使用して HUD を更新する
ここで、Print String ノードをプレイヤー向けの実際のフィードバックに置き換えます。 HUD を変更して、プレイヤーの HP をリアルタイムで報告します。
HUD に HP 変数を追加する
動的なプレイヤーのヘルス値を HUD に追加するには、次の手順に従います。
コンテンツ ブラウザで、
WBP_PlayerHUDウィジェット ブループリントを開きます。 [Designer (デザイナー)] ビューであることを確認します。Hierarchy で、txtHP ウィジェットをクリックします。 [Details (詳細)] パネルで、Is Variable を有効にし、Text プロパティから「100」を削除します。
グラフ ビューに移動して、txtHP の値を設定する新しい関数を設定します。
Functions (関数) セクションで、「fnSetHP」という名前の新しい関数を追加します。
関数を選択した状態で、[Details (詳細)] パネルで Inputs (入力) の横にある [+] をクリックします。
入力に
「NewHP」という名前を付けて、その型を [Float]に変更します。後で、ダメージを受けたときにこの関数を呼び出すようにプレイヤー キャラクターを変更します。
fnSetHP 関数のグラフで、関数 Entry ノードの後に SetText (Text) ノードを接続します。
ノード アクション リストでノードが見つからない場合は、Context Sensitive を無効にします。
SetText (Text) ノードを設定します。
Target に txtHP 変数への参照を接続します。 これは、プレイヤーのヘルスを表示するテキスト ウィジェットです。
In Text では 関数入力ノードの New HP 入力ピンに接続します。 Unreal Engine は、自動的に To Text (Float) ノードを追加して値を変換します。
ウィジェット ブループリントを保存してコンパイルします。
fnSetHP 関数全体のグラフは、次のようになります。
このブループリントの一部をグラフにコピーする場合は、関数のエントリ ノードを SetText のノードと To Text のノードに接続する必要があります。
プレイヤーの開始 HP を表示する
表示する前に利用可能な HUD 変数を設定します。 この場合、プレイヤーの開始時の HP がわかっているため、ゲームが開始したときにその情報を表示できます。
HUD に HP を表示するようにプレイヤー キャラクターのブループリントを更新するには、次の手順に従います。
コンテンツ ブラウザで、
BP_AdventureCharacterブループリントを開きます。 イベントグラフで Event Possessed ロジックを見つけます。[My Blueprint (マイ ブループリント)] パネルで [Graphs (グラフ)] > [EventGraph (イベント グラフ)] を展開し、Event Possessed をダブルクリックして、グラフ内でそのイベントにフォーカスします。
Set ノードと Add to Viewport ノードの間で、fnSetHP ノードを接続します。
Target では、Set ノードの出力ピンを使用して、HUD をターゲットにします。
For New HPに プレイヤーの Health 変数への参照を接続します。
Add to Viewport ノードの Target (ターゲット) ピンも、HUD 変数ノードに接続していることを確認します。
[My Blueprint (マイ ブループリント)] パネルで、Health 変数をクリックします。 [Details (詳細)] パネルで、デフォルト値を変更する (または維持する) 。 このチュートリアルでは、100 の開始ヒット ポイントを使用します。
保存してコンパイルします。
プレイヤーの新しいEvent Possessed ロジックは次のようになります。
このロジックをプロジェクトにコピーする場合は、まず既存の Event Possessed ロジック グループを削除します。
これで、ゲーム開始時に HUD にプレイヤーのヘルスが表示されるようになりました。 最後に必要なロジックは、プレイヤーがダメージを受けたときに HUD を更新することです。 これを行うには、キャラクターの既存のダメージ処理ロジックを HUD と連動するように変更します。
ダメージを受けた後にプレイヤーの HP を更新する
プレイヤーへのダメージを処理するには、次の手順に従います。
BP_AdventureCharacterのイベント グラフの左下隅にある、Event AnyDamage ノードから始まる、「ダメージおよびデス時の処理」というラベルの付いたロジックのセクションを見つけます。 ここでは、このセクションを変更して、独自のロジックを実行します。Branch ノードの後に続くすべてのノードを削除します。 Branch ノードを維持します。
ロジックのこのセクションでは、演算子ノードを使用して計算を実行します。 キャラクターがダメージを受けると、Event AnyDamage ノードがトリガーし、与えたダメージ、ダメージの型、ダメージを発生させたコントローラーとアクタに関する情報を渡します。 次に、ダメージはキャラクターの Health 変数から減算されます。 ヘルス値が差し引かれると、Branch ノードがプレイヤーのヘルス値が 0 に達したかどうかを確認します。
ここでは、プレイヤーのヘルスが「0」より大きいときに HUD を更新するロジックを作成します。 そのため、False ピンから、FnSetHP ノードに接続して、新しいヘルス値を HUD に送信します。
fnSetHP ノードを設定します。
ターゲットに、キャラクターのHUD変数への参照を接続します。
New HP 入力では、Health 変数への参照を接続します。
ブループリントを保存してコンパイルします。
これで、HUD にプレイヤーの現在のヘルスが表示され、プレイヤーがダメージを受けるとそのヘルス値が更新されます。
BP_TrapBase ブループリントに戻り、ベース トラップのイベント グラフに追加した Print String ノードをすべて削除します。
ゲームをもう一度プレイして、テストしましょう!
失敗とリスポーン条件を作成する
プレイヤーがヘルスを使い果たし、撃破されたら、ゲームを停止して、再挑戦するための機会を提供したいと思います。 このチュートリアルでは、プレイヤーのコントロールを無効にし、プレイヤーにゲームに敗北したことを通知して、レベルをロードします。
まず、撃破されたことをプレイヤーに伝える、ゲームオーバー ウィジェットのブループリントを作成します。
ゲームオーバー画面を追加する
ゲームオーバー画面のウィジェット ブループリントを作成するには、次の手順を実行します。
コンテンツ ブラウザで、で、「AdventureGame」>「Designer」>「Blueprints」>「Widgets」フォルダを選択し、右クリックして、[UserInterface (ユーザー インターフェース)] から [Widget Blueprint (ウィジェット ブループリント)] を選択します。
[Pick Parent Class (親クラスを選択)] ウィンドウで [User Widget (ユーザーウィジェット)] をクリックします。
ウィジェットブループリントに
WBP_EliminatedScreenという名前を付けて開きます。
ゲーム オーバー UI を設定するには、次の手順を実行します。
[Palette (パレット)] タブで、[Canvas (キャンバス)] を検索し、 [Hierarchy] パネルにある [WBP_EliminatedScreen] の上にキャンバスをドラッグします。 HUDと同様に、キャンバスはルートウィジェットです。
キャンバスには、テキストをより読みやすくするぼかしエフェクトの上にゲームオーバーのメッセージがレイヤー化されます。 [Palette (パレット)] タブで、オーバーレイをドラッグして、キャンバスの子にします。
オーバーレイを選択した状態で、[Details (詳細)] パネルの [Slot (Canvas Panel Slot)] セクションで [Anchors (アンカー)] を展開し、両方の最大値 (X と Y) を
1に変更します。その他のスロット プロパティ (アンカーの下) は、Offset 設定に変わります。
HUD をビルドするとき、すべてのアンカー ポイントを 1 つの隅に残しておくと、スクリーン サイズが変わっても、これらのオブジェクトはアンカー ポイントにアンカーされたままになります。 現在、オーバーレイはキャンバス バウンディング ボックス全体に固定されているため、オーバーレイは画面サイズに一致して伸縮します。
アンカーの設定を変更すると、オーバーレイ パネルのデフォルトの形状を維持するために、エディタによっていくつかのオフセット値が変更されます。 これを削除するには、[Offset Right] と[Offset Bottom]を
「0」に変更します。 これでオーバーレイが画面全体に表示されます。[Palette (パレット)] タブで、[Background Blur (背景ブラー)] ウィジェットをドラッグして、[Overlay (オーバーレイ)] パネルの子にします。
ブラー エフェクトを選択した状態で、[Details (詳細)] パネルの Slot (Overlay Slot) セクションで、次の設定を変更します。
[Horizontal Alignment (水平のアライメント)] を [Fill Horizontally (水平方向にフィル)] に設定します。
[Vertical Alignment (垂直アライメント)] を [Fill Vertically (垂直方向をフィルする)] に設定します。
[Appearance] セクションで [BlurStrength] を
「5」に変更します。[Palette (パレット)] タブで、Text ウィジェットを Overlay の子として追加します。
Text ウィジェットを選択した状態で、[Details (詳細)] パネルの Slot (Overlay Slot) セクションで、次の設定を変更します。
[Horizontal Alignment (水平アライメント)] を [Center Align Horizontally (水平方向に中央揃え)] に変更します。
[Vertical Alignment (垂直アライメント)] を [Center Align Vertically (垂直方向に中央揃え)] に変更します。
[Content (コンテンツ)] セクションで、[Text (テキスト)] を [
You areキャラクターを撃破し、レベルを再起動する] に変更します。Appearance セクションで、次のプロパティを設定することでテキストを大きくし、より読みやすくします。
[Color and Opacity (色と透明度)] の横にある色見本をクリックして、テキストの色を選択します。 このチュートリアルではピンクを使用しています (Color Hex sRGB =
FF4D7AFF)。[Font (フォント)]ヘッダを展開して[Size (サイズ)]を
「60」に変更します。[Font] > [Outline Settings] を展開して [OutlineSize]
1に変更します。
12なので ブループリントを保存してコンパイルします。
失敗条件のロジックをビルドする
ゲームオーバー画面ができたので、キャラクター クラスを変更して、プレイヤーの HP がなくなったときにこれを表示することができます。 この場合、以前に使用した Branch ノードの True の結果が実行されます。
プレイヤーの敗北を処理するには、次のことを行う必要があります。
プレイヤーが移動できないようにプレイヤー入力を無効にします。
ゲームオーバー画面を表示します。
一定時間待機してからレベルを再開します。
プレイヤーが撃破されたときにゲームを停止してロードするには、次の手順に従います。
BP_AdventurePlayerで、キャラクター ブループリントのダメージ処理ロジック (Event AnyDamage で始まる) に戻ります。Branch ノードの True 実行ピンの後に、Do Once ノードと Disable Input ノードを接続します。
プレイヤーは、ヘルスがなくなってもヒットを受け続けることができるため、Do Once ノードにより、その後のロジックが 1 回だけ実行されるようにすることができます。
Disable Input ノードの Player Controller (プレイヤー コントローラー) ピンでは、Get Player Controller ノード (ノード アクション リストの Game > Player セクション) を接続します。
ここには Get Player Controller という名前のノードがあります。 ノードに Player Index 入力ピンがあることを確認します。 インデックス 0 は、レベルにスポーンされた最初のプレイヤー キャラクターのデフォルトのインデックスです。
プレイヤー コントローラーを無効にした後、ゲームオーバー画面を作成して表示します。
Create Widget ノードを接続します。 このノードで Class を
WBP_EliminatedScreenに変更します。ウィジェット ノードの exec ピンと Return Value ピンを Add to Viewport ノードに接続します。
ディレイ時間を追加し、現在のレベル名を取得して、そのレベルをロードします。
Add to Viewport ノードの後に、Delay ノードを接続し、[Duration] を
5秒に変更します。Delay の後ろに Get Current Level Name ノードを接続します。
Get Current Level Name の後ろに Open Level (by Name) ノードを接続します。
Return Value ピンを Level Name ピンに接続します。 エディタが自動的に、文字列から名前への変換ノードを追加します。
プレイヤー ブループリントを保存してコンパイルします。
この BP_AdventureCharacter イベント グラフのセクションは次のようになります。
このロジックをプロジェクトにコピーする場合、既存の Damage handling ノードのグループ (イベント AnyDamage ロジックとイベント Destroyed ロジックを含む) をまず削除してください。
レベルをプレイしてテストします。 トラップにかかり、キャラクターの HP がすべて失われて、ゲームが意図したとおりにリセットされることを確認します。
パズルに危険な要素を追加する
パズル:スイッチとキューブでは、難易度、緊張感、結果、リスクと報酬の決定を追加するゲームプレイ メカニクスの設計について学びました。 プレイヤーにダメージを与える環境ハザードは、そのような結果をもたらすメカニクスの 1 つです。 スパイク トラップを使用すると、レベル内にある初期のパズルや障害物に危険や追加の結果を追加することができます。また、スイッチ式のトラップを使用すると、プレイヤーが環境とインタラクションして安全なパスを見つけることができる、よりダイナミックなパズルを作成できます。
ゲームの設計時にオーバーヘッドを削減して開発速度を向上させるうえで重要なのは、ゲームプレイ オブジェクトを使用および組み合わせる複数の方法を見つけることです。 このチュートリアル シリーズの前のセクションでは、スイッチによって動作するパスを作成するために、プラットフォームに依存しないようにしました。 ここでは、同じスイッチでファイア トラップを無効にし、プレイヤーのためのパスを明らかにすることができます。 これにより、一意のシステムを無限に作成することなく、レベルに多様性がもたらされます。
このチュートリアル シリーズで以前に作成したドアとキーのゲーム メカニックと同様に、ファイア トラップは、プレイヤーのペースと環境へのアクセスを管理するための別のメカニックになります。
ファイア トラップで迷路パズルを作成する
ルーム 2 では、スイッチとトラップを組み合わせて迷路パズルをビルドします。このパズルでは、プレイヤーが最後の鍵を発見して収集するために、慎重に危険を無効にしなければなりません。
まず、紙にパズルのスケッチを描くと役立ちます。 トラップは 1m x 1m であるため、サンプル ルーム 2 には 7 x 9 のグリッドのトラップがフィットします。 キーで終わるグリッドを通るパスを描画することから始めます。 次に、パスをセグメントに分割し、各セグメントを制御するスイッチを配置します。
難易度を上げ、さらなる発見や驚きを生み出すため、視線を遮る建築物を追加します。 たとえば、壁や柱の後ろにスイッチを配置し、プレイヤーがパスに沿ってスイッチを発見できるようにします。
このループするパスにより、プレイヤーはパスの最初のセグメントを通過しながらゴールを発見できるように、キーが一目でわかります。
計画が完了したら、レベル エディタでパズルのブロックアウトを開始します。
鍵へのパスと新しいブロックアウト形状を作成したら、部屋の残りの部分にトラップを埋めて正しいルートを隠します。
アウトライナーでレベル オブジェクトの名前を変更し、各スイッチが制御するファイア トラップを明確にします。 たとえば、BP_Switch1 が 3 つのトラップをオフにする場合、それらに BP_FireTrap_S1_0、BP_FireTrap_S1_1、BP_FireTrap_S1_2 という名前を付けます。 追加のファイア トラップの名前を BP_FireTrap_Extra などに変更し、パズルの一部ではないことを示します。
必要に応じて、鍵の下に最終スイッチを追加して、プレイヤーがパズルを完了したときに脱出できるようにすることができます。
サイトライン、フラストレーション ポイント、および可能なショートカットに注意して、パズルを頻繁にテストします。 フレンドを手伝ってもらう。予想していなかったループホールが見つかるかもしれません。 プレイテストをしているうちに、プレイヤーがパズルの一部をスキップしないようにするために、調整が必要な場合があります。
不具合が生じる場合、以下の 2 つのオプションがあります。
パスまたはパズルを再配置する。
建築ブロッカーを追加する。
火属性のダメージを増やして、パスから外れるとより厳しい結果にします。
エクスプロイトをそのままにして代わりにコストを増やすことで、プレイヤーに選択肢と自律性を与えることができます。 プレイヤーは、安全なパスを見つけるために時間を費やすか、HP を犠牲にして急いでキーを見つけるかの選択を行うことができます。
サンプル レベルのパズルでは、プレイヤーが鍵を見ることができるように、アーチ道の下に岩を追加しました。ただし、プレイヤーは直接そこにスキップできません。 また、報酬の一部を明らかにするためだけでなく、パスのその部分のスキップを防ぐためにもスイッチを非表示にしています。
過去の障害物にスパイクを追加する
過去のパズルにスパイクを追加して 落下に対する結果を追加しましょう
ルーム1のパズルから始めます。 最初の移動するプラットフォームでは、プレイヤーが落下しても登ってやり直すように、危険度を低く維持してください。 新しいメカニズムを導入するときは、プレイヤーが学習に集中できるように、安全な場所で学習できる余地を提供します。
同様に、Start Room では、最初のキーの下にある穴にスパイクを追加できます。 プレイヤーは、最初の 2 つのプラットフォームでジャンプの練習をして、最後のリスクが高いキーへのジャンプに備えます。 これで、最初のキーを無傷で獲得することが、より楽しくなります。
プレイヤーが基本を理解し、プラットフォームやスイッチ上のブロックを動かす練習をしたら、結果を追加します。 2 番目のプラットフォームまたは 3 番目のボタンの下には、スパイク トラップを配置します。 これで、プレイヤーが落下するとダメージを受けますが、そのダメージを最小限に抑えるように、プレイヤーは素早くトラップを解除することができるため、緊張感を高めることができます。
最後に 最後のプラットフォームとスイッチの場合は 危険度を上げ続けます スパイクから抜け出すためにさらに走らなければならなくなり、より多くのダメージを受けるように、下のエリアをスパイクで覆うようにします。 この時点では、プレイヤーはそのメカニクスに精通しているはずであり、ミスに対する結果は、プレイヤーがすでに練習していたため、より公平に感じられるものとなります。
このデザインは、プレイヤーにゲームプレイのメカニクスを紹介する際によく使用される構造に従っています。
紹介:最初のプラットフォームでは、ゲームの仕組みを安全に学習できます。
構築:2 番目のプラットフォームとキューブは、適度なリスクでプレイヤーのスキル向上を試します。
応用:最後のプラットフォームにより危険度が増し、新しい移動方向が追加され、メカニクスが難易度の高いものになります。
「パズル:プラットフォームを動かす」のゲームプレイ デザイン レッスンで学んだように、パズルにおける結果を大きくすることで、公平性と興奮のバランスを保つことができます。
トラップのダメージを変更する
ある型のトラップのダメージを増減することで、難易度レベルを変更することができます。 次の 2 つの方法のいずれかでそれを行うことができます。
アウトライナーで「スパイク」または「ファイア」を検索し、その型のトラップをすべて選択します。 [Details (詳細)] パネルで、[Setup (設定)] > [Base Damage (基礎ダメージ)] を必要に応じて変更します。 このメソッドでは、レベルに追加するトラップの新しいインスタンスの [Base Damage (基礎ダメージ)] も変更する必要があります。 または、既存のトラップを複製して新しいトラップのインスタンスをレベルに追加することで、新しいインスタンスごとに編集する必要がなくなります。
または
子トラップのブループリントの 1 つを開き、その [Construction Script (コンストラクション スクリプト)] タブに移動します。 [My Blueprint (マイ ブループリント)] パネルでは継承された変数を編集できませんが、グラフで変数を設定することができます。 2 つの Construction Script ノードの後ろに Set Base Damage ノードを接続します。 ノードで、必要に応じて Base Damage 値を変更します。
ゲームプレイ オブジェクトがプレイヤーにとって予測可能であることを確保するために、1 つの型のトラップすべてが同じダメージを与えるようにします。
チュートリアルのサンプル レベルでは、ファイア トラップは毎秒 5 ダメージを与え、スパイク トラップのインスタンスは毎秒 10 ダメージを与えるように変更されています。
サンプル レベルを試す
独自に作成するのではなく、チュートリアルのこのパートでデザインされた部屋の一部を使用したい場合は、以下のスニペットをコピーします。
ルーム 2 のブロックアウト
このテキスト スニペットには、ルーム 2 の床、壁、およびこのルームのパズルを作成するために追加された新しいブロックアウト形状が含まれます。 アウトライナーでは、すべての形状 が「Room2」という名前のフォルダにあります。
Begin Map
Begin Level
Begin Actor Class=/Script/Engine.TextRenderActor Name=TextRenderActor_19 Archetype="/Script/Engine.TextRenderActor'/Script/Engine.Default__TextRenderActor'" ExportPath="/Script/Engine.TextRenderActor'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19'"
Begin Object Class=/Script/Engine.TextRenderComponent Name="NewTextRenderComponent" Archetype="/Script/Engine.TextRenderComponent'/Script/Engine.Default__TextRenderActor:NewTextRenderComponent'" ExportPath="/Script/Engine.TextRenderComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19.NewTextRenderComponent'"
End Object
Begin Object Class=/Script/Engine.BillboardComponent Name="Sprite" Archetype="/Script/Engine.BillboardComponent'/Script/Engine.Default__TextRenderActor:Sprite'" ExportPath="/Script/Engine.BillboardComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19.Sprite'"
End Object
Begin Object Name="NewTextRenderComponent" ExportPath="/Script/Engine.TextRenderComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19.NewTextRenderComponent'"
Text=NSLOCTEXT("[3C535F7772EB3B3657484B5E2D5B925D]", "2347F80B407C68C27836E990A20143CF", "Room 2")
HorizontalAlignment=EHTA_Center
ルーム 2 のブロックアウトをすべてコピーするには、次の手順を実行します。
ルーム 2 にすでにあるもの (または廊下 2 の端にあるもの) を削除します。
アウトライナーを使用して、ルーム 2 の既存のコンテンツを選択します。
「Room2」フォルダを右クリックし、[Select (選択)] > [Immediate Children (直接の子)] を選択します。 [Delete (削除)] を押します。または、ビューポートを正投影の上面ビューに切り替えて、手動で既存のルームを選択して削除します。
Copy Full Snippet (フルスニペットをコピー) をクリックします。
Unreal エディタ で、ビューポート がアクティブな パネル であることを確認し (ビューポートまたはアウトライナー内の任意の場所をクリックしてから Esc キーを押す)、Ctrl + V を押します。
レベルとアウトライナーは次のようになります。
ルーム 2 のスイッチ、トラップ、キー
このテキスト スニペットにはパズルのスイッチ、トラップ、赤色のキーが含まれます。 アウトライナーでは すべてのオブジェクトが「Room2」という名前のフォルダにあります。
プロジェクト間でブループリント インスタンスをコピーするには、親ブループリント アセットが完全に同一であり、ファイル名と場所が同じである必要があります。 プロジェクトでブループリントのコンポーネント、変数名、またはプロパティを変更した場合は、スニペットが想定どおりにコピーされない場合があるため、これらのレベル オブジェクトを手動で設定する必要があります。
Begin Map
Begin Level
Begin Actor Class=/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C Name=BP_FireTrap_C_261 Archetype="/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.Default__BP_TrapFire_C'" ExportPath="/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261'"
Begin Object Class=/Script/Engine.SceneComponent Name="DefaultSceneRoot" Archetype="/Script/Engine.SceneComponent'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C:ICH-DefaultSceneRoot_GEN_VARIABLE'" ExportPath="/Script/Engine.SceneComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.DefaultSceneRoot'"
End Object
Begin Object Class=/Script/Engine.StaticMeshComponent Name="TrapBase" Archetype="/Script/Engine.StaticMeshComponent'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C:TrapBase_GEN_VARIABLE'" ExportPath="/Script/Engine.StaticMeshComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.TrapBase'"
End Object
Begin Object Class=/Script/Engine.BoxComponent Name="TrapTrigger" Archetype="/Script/Engine.BoxComponent'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C:TrapTrigger_GEN_VARIABLE'" ExportPath="/Script/Engine.BoxComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.TrapTrigger'"
End Object
Begin Object Name="DefaultSceneRoot" ExportPath="/Script/Engine.SceneComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.DefaultSceneRoot'"
パズルのブループリントのピースを設定するには、次の手順に従います。
[Copy Full Snippet (フルスニペットをコピー)] をクリックします。
Unreal Editor で、[ビューポート] または Outliner がアクティブなパネルであることを確認してから、Ctrl + V キーを押します。
各スイッチの [Setup (設定)] プロパティを確認し、必要であれば、各スイッチをそのファイア トラップに再接続します。
アウトライナの
「Room2」フォルダでの「BP_Switch4」をクリックします。[Details (詳細)] パネルの [Setup (設定)] セクションで、[Interact Object List (インタラクト オブジェクト リスト)] を展開します。
リスト内の各要素について、ドロップダウンをクリックし、
S4を検索し、S4のラベルが付いたファイア トラップの 1 つを選択します。各スイッチに対して、これらの手順を繰り返します。
BP_Switch5はBP_FireTrap_S5_0-7をトリガーしますBP_Switch6がBP_FireTrap_S6_0-3をトリガーしますBP_Switch7がBP_FireTrap_S7_0-4をトリガーしますBP_Switch8はBP_FireTrap_S8_0-3をトリガーしますBP_Switch9はキーの下でBP_FireTrap_S9_0-4をトリガーします
レベルとアウトライナーは次のようになります。
次の内容
次は、もう 1 つの一般的なハザードである敵 NPC をゲームに追加する方法について説明します。 敵がプレイヤーを見つけてダメージを与えることができるように、AI の敵キャラクターを作成し、レベルにナビゲーション メッシュを追加する方法について説明します。