ボイスオーバーを利用したダイアログは、現代のビデオゲームに欠かせない要素の1つです。プレイヤーが特定の音声にキャラクターを結び付けるだけでなく、全般的な声の抑揚からキャラクターの心情がとらえやすくなります。これを、プレイヤーの言動に応じてキャラクターの発言内容や言い回しを変化させる、複雑なダイアログシステムが強化します。
キャラクターは、プレイヤーが過去に頼み事を聞いてくれた場合、より親切な反応を示すかもしれませんし、自分の倫理観に著しく反することをした場合、より攻撃的に行動するかもしれません。これがいわゆるダイナミックダイアログです。
今回のデモでは、ナレーションを中心としたダイアログに焦点を当て、WwiseとUnreal Engineを使ってダイアログを実行します。Wwiseにはビデオゲームにダイナミックダイアログを実装する機能がありますが、今回は別のWwise機能を使ってダイアログシステムを動かします。今回の記事では、主に3つの領域を見ていきます。
1. プレイヤーによる決定に左右されない、シーケンスコンテナを使った基本的なナレーション。
2. 複数言語に対応するゲームのデザインを行っている人向けの、Wwiseのローカリゼーションシステム。
3. プレイヤーの影響を受ける変数に応じて変化する、スイッチコンテナを使ったダイナミックなナレーション。
これらのデモでは、Wwiseのシーケンスコンテナやスイッチコンテナについて学べるだけでなく、Wwiseに関する追加的なUnreal Engineのブループリント(イベントのポスト、ディレイ、スイッチやステートの変更など)も紹介します。
先週、これらをWwiseとUnityで行う方法について書きました。興味のある人は、こちらで読んでみてください。
Wwise - シーケンスコンテナを使ったナレーションとローカリゼーション
最初のデモでは、プレイヤーに指示を出す指揮官のボイスオーバーをデザインします。指示は5つの異なるボイスオーバーに分割し、次々と再生されるようにプログラミングします。
1. “Hello? Hello? Can you hear me?”(「ハロー、ハロー。聞こえますか、どうぞ。」)
2. “Oh good. Listen, I need you to do something very, very important for me.”(「よし。聞いてくれ、君に非常に重要な任務を与える。」)
3. “In front of you are these little... obstacles that I need you to overcome.”(「君の前に、何と言えばいいのか…小さな障害物がある。それらを乗り越えてほしい。」)
4. “I just need you to jump over the hurdle, go under the archway, and to the green path. Not the red one. That would be bad.”(「ハードルを飛び越えて、アーチをくぐり、緑の道へと進んでほしい。赤の道ではないぞ。それはまずい。」)
5. “If you could do that for me, that would greatly help us over here in corporate. Over and out.”(「そうしてもらえれば、本社の方では非常に助かる。以上だ。」)
このナレーションは、状況に関わらずゲーム開始時に全く同じように再生され、変更される可能性はありません。そこでシーケンスコンテナを使用して、各オーディオトラックが変更されることなく次々と再生されるようにします。また、プレイヤーの好みに応じて英語またはスペイン語でオーディオを再生するため、Wwiseのローカリゼーションシステムも見ていきます。
まず、Audioタブから始めます。Actor-Mixer Hierarchyの下に新しいシーケンスコンテナを作成(Ctrl + Shift + Alt + Q)し、MissionBriefingという名前にします。次に、オーディオファイルを、新しいシーケンスコンテナの下にアップロードします。この操作を行うには、シーケンスコンテナを右クリックして“Import Audio Files...”を選択するか(Shift + i)、オーディオファイルをシステムからシーケンスコンテナにドラッグします。
Audio File Importerで、「Import as: 」フィールドを「Sound SFX」から「Sound Voice」に切り替え、「Import」をクリックします。
サウンドボイスはサウンドSFXと同じですが、Wwiseプロジェクトで使用されている全言語に対応する、複数のオーディオファイルをインポートできます。言語設定を変更すると、すべてのサウンドボイスがその言語のオーディオファイルに切り替わります。
さて、英語のサウンドファイルをすべてインポートできたので、Wwiseプロジェクトに他の言語を追加できるようにしましょう。これを行うには、トップバーのProjectを開き、Languagesを選択します(または、Shift + Jを押します)。Language Managerでは、言語の追加、削除、名前変更のほか、すべてのサウンドボイスのゲインを言語ごとに変更できます。とりあえず、Addボタンを押して、表示されたボックスにSpanishと入力してみましょう。「OK」をクリックし、続いて表示される警告メッセージで変更内容を確認します。
新しく作成したサウンドボイスを1つ選択してみると、Contents Editorに英語とスペイン語用に2つのセクションが表示されます。英語のオーディオファイルはすでに用意されているので、スペイン語のオーディオファイルをContents EditorのSpanishフィールドにぞれぞれドラッグしてインポートしましょう。この操作を、5つのナレーション音すべてで行います。
これらのサウンドボイスを再生すると、デフォルトの言語で聞こえます。ここでWwiseの左上でデフォルトの言語からスペイン語に切り替え、もう一度サウンドを再生すると、Spanishフィールドに入れたサウンドが聞こえてきます。このように、開発者がスイッチ1つで簡単に、ある言語から別の言語に変更することができます。
それでは、シーケンスコンテナを確認してみましょう。コンテナを選択した後、Contents Editorと、その右にあるPlaylistセクションを見てみます。デフォルトでは、シーケンスコンテナは内部のすべてのサウンドオブジェクトを再生するわけではなく、プレイリストに含まれるサウンドオブジェクトのみを再生します。サウンドボイスを、再生したい順番通りにContents EditorからPlaylistにドラッグします。
サウンドを編集したい場合を除いて、ここで行う操作はこれで終わりです。Eventsタブを開き、Default Work Unitに2つの新しいイベントを作成します。
1. Play_MissionBriefingという名前の「Play」アクションのイベント。シーケンスコンテナを再生します。
2. Reset_MissionBriefingという名前の「Reset Playlist」アクションのイベント。シーケンスコンテナのプレイリストを最初のサウンドオブジェクトにリセットします。
注:今回の一連のデモでは、ダイナミックダイアログシステムの作業を行いますが、EventsタブのDynamic Dialogue部分は使用しません。
2つ目のイベントの目的は、Narration(ナレーション)を再生する時は常に、必ずシーケンスコンテナの最初のサウンドから再生されるようにすることです。セーフティーネットのようなものです。
あとは、サウンドバンクを作成して、2つの新しいイベントを入れるだけです。トップバーの「Layouts」でSoundBankレイアウトを選択するか、F7を押します。SoundBank ManagerでNewを選択し、新しいサウンドバンクを作成します。私はこれをMainと呼ぶことにします。
SoundBank Managerで新しいサウンドバンクを選択し、Play_MissionBriefingイベントとReset_MissionBriefingイベントの両方を、Event ViewerからSoundBank Editorにドラッグします。
SoundBank Managerで、新しいサウンドバンク、プラットフォーム(Windows、Macなど)、プロジェクトのためにつくった言語の、それぞれのチェックボックスにチェックを入れます。最後に「Generate Selected」ボタンを押します。
Wwise - ダイナミックダイアログ
プレイヤーは、指揮官からミッションを与えられた後、ミッションをクリアする時間を与えられます。プレイヤーが、どのようにミッションをクリアしたかによって、指揮官の返答も変わってきます。始める前に、プレイヤーに対する指揮官の発言を決定する変数をマッピングします。まず、プレイヤーに与えられた3つの目的を見てみましょう。
1. ハードルを越える。
2. アーチをくぐる。
3. 赤の道ではなく、緑の道を進む。
このミッションの終わり方は複数あります。正確には5通りです。
1. プレイヤーは何もしない。(失敗、失敗、失敗)
2. プレイヤーは「ハードルを越える」だけをクリアする。(成功、失敗、失敗)
3. プレイヤーは「ハードルを越える」と「アーチをくぐる」をクリアする。 (成功、成功、失敗)
4. プレイヤーは「ハードルを越える」と「アーチをくぐる」をクリアし、赤の道を進む(成功、成功、赤)
5. プレイヤーは「ハードルを越える」と「アーチをくぐる」をクリアし、緑の道を進む(成功、成功、緑)
つまりハードル、アーチ、道の3つの変数を追跡することになります。ここで登場するのが、スイッチやステートです。
まだSoundBankレイアウトを開いている場合は、「Layouts -> Designer」を選択するか、F5を押して、Designerレイアウトに戻ります。
Project ExplorerのGame Syncsタブを開き、SwitchesセクションのDefault Work Unitに、3つの新しいスイッチグループとして、Hurdle(ハードル)、Archway(アーチ)、Path(道)を作成します。HurdleとArchwayの両スイッチグループに、Fail(失敗)とPass(成功)の2つの新しいスイッチを作ります。Pathスイッチグループには、Fail、Red(赤)、Green(緑)の3つの新しいスイッチを作ります。
Audioタブに戻ります。Actor-Mixer Hierarchyで、Default Work Unitの下に新しいスイッチコンテナを作ります(Ctrl + Shift + Alt + W)。私はこれをMissionResultと名付けます。
新しく作成したスイッチコンテナを選択し、Property Editorの右側にある「Switch」の設定を見ます。このコンテナでは、まず初めに、プレイヤーがHurdleテストに成功したか失敗したかを確認します。失敗した場合は、落胆した指揮官の音声が再生されます。成功した場合は、Archwayテストに進みます。
そのために、まずSwitchのGroupをHurdleグループに設定し、Default Switch/StateをFailに設定します。これにより、下のAssigned Objectsに、PassとFailの2つのスイッチが表示されます。今度はこれらに対応する適切な“オブジェクト”が必要です。
まず、MissionResultスイッチコンテナに、“hurdlefailed(ハードルに失敗)”という条件の新しいオーディオファイルをインポートします。次に、MissionResultコンテナの中に新しいスイッチコンテナを作り、これをArchwayと名付けます。
あとは、この2つをContents Editorから、それぞれのAssigned Objectsに移すだけです。“hurdlefailed”を“Fail”に、“Archway”コンテナを“Pass”に移動します。
今度は、Archwayスイッチコンテナの中で、この手順を繰り返します。SwitchのGroupをArchwayスイッチグループに設定し、Default Switch/StateをFailに設定します。“archwayfailed(アーチに失敗)”のオーディオをArchwayコンテナにインポートし、Pathという名前のスイッチコンテナを新しく作成します。あとは、先ほどと同じようにAssigned Objectsに入れるだけです。“archwayfailed”を“Fail”に、“Path”コンテナを“Pass”に入れます。
最後にもう一度この手順を繰り返しますが、スイッチの数は2つから3つに増えています。Pathスイッチコンテナの中で、SwitchのGroupをPathスイッチグループに設定し、Default Switch/Stateは今回もFailに設定します。
あとは、最後の3つのオーディオファイルpathfailed(道に失敗)、pathred(赤の道)、pathgreen(緑の道)をインポートするだけです。3つとも、対応するAssigned Objectsに入れます。
それでは、今の内容を簡単にまとめます。Hurdleテストに失敗すると、他のスイッチコンテナは表示されず、「ハードルに失敗」のメッセージが再生されるだけです。成功すると、Archwayテストに進みます。Archwayテストに失敗すると、Pathスイッチコンテナは表示されず、「アーチに失敗」のメッセージが再生されます。Archwayテストに成功すると、最後のPathスイッチコンテナへと移動します。ここで、赤の道に進んだか、緑の道に進んだか、どちらの道にも進まなかったか、確認します。3つの条件のいずれに合致するかに応じて、対応するオーディオファイルが再生されます。
以上が完了したら、イベントの作成は簡単です。イベントを、Eventタブではなく、Audioタブで作成します。MissionResultスイッチコンテナを右クリックして、New EventからPlayを選択してください。これにより、Play_MissionResultという名前の新しいPlayイベントが自動的に作成されます。
F7を押してSoundBankレイアウトに戻り、新しいPlay_MissionResultイベントを、Event ViewerからSoundBank Editorにドラッグします。先ほどと同じようにサウンドバンクを生成したら、必ずWwiseプロジェクトを保存してください。
Unreal Engine – シーケンスのNarrationの統合
次にシーケンスコンテナで作ったナレーションを統合していきます。通常であれば、ナレーションのオーディオを5回連続して再生するだけの簡単な作業です。でも1つのオーディオが終わるタイミングが分からなければ、次のオーディオの再生を開始できません。オーディオとオーディオの間に、わずかなディレイを入れたい場合もあります。この2つを実現する1つの方法として、イベントコールバックとコルーチンの活用があります。
最初にバンクをロードする必要があります。Content Browser内で右クリックし、「Audiokinetic -> Audiokinetic Bank」を選択してください。新しいバンクに、Wwiseのサウンドバンクと同じ名前を付けます(私はMainと名付けました)。
次に、Wwise Pickerウィンドウが開かれていることを確認します。開いていない場合は、トップバーで「Window -> Wwise Picker」を選択します。ここに、あなたのWwiseコンポーネントがすべて表示されます。表示されない場合は必ず、サウンドバンクをWwiseでもう一度生成してWwiseプロジェクトを保存するか、Unreal EngineのWwise Pickerウィンドウで「Populate」ボタンを押してください。
Eventフォルダに移動し、3つのイベントをContent Browserにドラッグします。見やすいように、Content Browserで1つのフォルダに保存しておくと便利かもしれません。イベントをすべて選択して右クリックし、「Group Into Sound Bank」を選びます。ここで作成されたバンクを探してクリックし、Selectを押します。
最後に、バンクを右クリックしてGenerate Selected SoundBankを選択し、Generateを押します。
これでスクリプト作成を開始する準備が整いました。ビューポートの上にあるBlueprintsタブを開き、「Open Level Blueprint」を選択します。Event Graphを見ると、赤いヘッダが付いたボックスが複数あります。ここで使うのは「Event BeginPlay」のみなので、他は無視してください。
白い矢印の“実行ピン(Exec Pin)”をクリックして、Event BeginPlayの右方向へドラッグします。「Audiokinetic -> Actor -> Post Event」を選択するか、単純に検索バーで「Post Event」を検索します。
ノードを配置できたら、2つの値、つまりポストするAk Eventと、このイベントのポスト先となるActorを、ノードに関連付けます。イベントの方は簡単です。「Select Asset」ドロップダウンリストから、先ほど作成した「Reset_MissionBriefing」イベントを選択するだけです。
次にActorを追加します。今回のデモでは、毎回プレイヤーになるように設定します。プレイヤーを設定するには、青い「Actor」ピンをクリックしてそこからドラッグし、「Get Player Character」を検索するだけでいいのです。
今度は、同じことを繰り返しますが、1つだけ小さな違いがあります。Post Eventの実行ピンからドラッグし、「Post and Wait for End of Event」を検索し選択します。この便利な関数が、イベントをポストし、イベントの終了を待ってから、残りのスクリプトを続けます。
AkEventには「Play_MissionBriefing」イベントを選択します。先ほどと同じ「Get Player Character」ノードを使って、この関数のActorにも接続します。
これで、シーケンスコンテナのプレイリストをリセットし、続いてこのコンテナの最初のナレーションオーディオを再生するところまでできました。それではこのイベントを、あと4回、しかも4回だけ、再生するようにします。それから、各ナレーションの間に短いディレイも入れたいですね。まずはそこから始めましょう。
「Post and Wait For End of Event」の実行ピンから、Delay関数を検索し選択します。この単純な関数で、残りのスクリプトをDuration分だけ遅らせることができます。私はこれを「1」に設定しますが、好きなように設定してください。
次に、新しい変数を作成する必要がありますが、これにはInteger(整数)を使います。この変数の目的は、イベントの再生回数をカウントすることです。イベントが5回再生されたら、もう再生されないようにする必要があります。
新しい変数を作成するには、My BlueprintウィンドウのVariablesタブで、「+」記号をクリックします。私は、この変数をNarrationCountと名付けます。新しい変数を作成した時はいつでも、別のことをする前に、すぐにBlueprintの「Compile」ボタンを押すようにします。新しい変数をコンパイルすることで、その変数の値をより細かく編集できるようになります。
続いて右側のDetailsウィンドウでVariable Typeを変更します。Variable Typeのドロップダウンリストを開き、Integerを選択してください。この変数に関しては、以上です。
Variablesタブから、新しい変数をEvent Graphにドラッグし、Delayノードの下に配置します。この変数をGet(取得)またはSet(設定)するオプションがあります。
1. GETを使えば、変数の現在値を取得できます(この場合は「0」です)。
2. SETを使えば、変数に新しい値を設定できます(この値は1526434568としておきます)。
今回は、Narration CountをGetします。この値を1ずつインクリメントさせ、イベントをもう1回再生したことを示します。そのためには、Narration Countのピンからドラッグし、「Increment Integer」を検索し選択します。「++」と示されたノードが表示されます。これは単に「現在の値 + 1」を表しているだけです。
あと少しです。次は、イベントを5回再生したかどうかの確認です。そのためには、まず「++」ピンからドラッグし、「Integer < Integer」を検索し選択します。「<」関数の空のピンには、単に「5」の値を入力します。
「<」関数の赤いピンから、「Branch」マクロを検索し選択します。Branchの目的は、基本的にはステートメントがTrue(真)かFalse(偽)かを確認することです。今回の場合は、Narration Countが「5」未満かそうでないかを確認します。「5」未満であれば、ループバックし、もう一度イベントを再生します。「5」未満でなければ、ナレーションを終了します。
これを実現するには、BranchのTrueの実行ピンを、「Post and Wait for End of Event」関数の一番左にある実行ピンまでドラッグします。
注:この操作で、すべてのノードを横切る白線が作成され、あまり見た目が良くないかもしれません。白線をダブルクリックすると、Reroute Nodeが作成され、ノードを貫通せずに周りを回ることができます。
以上です!ブループリントの全体図を以下に示します。
メインエディターに戻る前に、必ずブループリントをコンパイルし、作業内容を保存してください。さっそくPlayを押して作品をチェックし、すべて正しく動作することを確認しましょう。また、各ナレーションオーディオ間のディレイが長すぎたり短すぎたりする場合は、Delay関数のDurationを自由に調整してください。
Unreal Engine – ミッション結果の統合
ミッションの説明を受けたプレイヤーは、いよいよミッションに赴きます。ゲーム側は、プレイヤーが実際にハードルを越え、アーチをくぐり、緑または赤の道に進んだかどうかを把握する必要があります。そこでハードル、アーチ、そして2本の道に、ボックストリガーを設けます。
「Place Actors」ウィンドウのBasicタブを開いて一番下までスクロールし、Box Triggerアクターを選択してビューポートにドラッグします。目的は、プレイヤーが必ずぶつかるようにBox Triggerを配置することです。ボックスは、移動(w)、回転(e)、スケール(r)の各ツールを使って自由に調整してください。
HurdleボックストリガーのDetailsウィンドウに移動し、青い「Blueprint/Add Script」ボタンを選択します。表示された画面内で、ブループリントに好きな名前を付けてください。私はBP_SetSwitchと名付けます。Selectを押すとブループリントが表示されます。
表示されたら、Event Graphタブに移動します。ここでの目的は、プレイヤーが実際にハードルを越えたことを示すため、HurdleのWwise SwitchをPassに設定することです。ここで使用するイベントはEvent ActorBeginOverlapだけですが、これはボックストリガー内に該当するオブジェクトが入るたびにアクティブになります。ここで、トリガーに当たったのがプレイヤーかどうかを確認します。
実行ピンから、「Cast to PlayerController」を検索し選択します。またOther Actorピンも、「Cast to PlayerController」のObjectピンにつなげます。
次にCastの実行ピンから、「Set Switch」関数を検索し選択します。「As Player Controller」ピンから「Actor」ピンにドラッグしてください。
今度は、Switch Valueをドロップダウンメニューから選択する代わりに、Switchを別の変数として設定します。まさしくこのブループリントを使ってアーチのスイッチも設定するので、スイッチを2つの異なる値に設定できるようにする必要があるためです。
そこで、Switch Valueピンからドラッグし、「Promote to Variable」を選択します。これによって自動的に、変数の名前が決まり、タイプがAk Switch Variableに設定されます。これで問題ありません。あとは、変数のすぐ右にあるアイコンを押して有効にするだけです(Detailsウィンドウの「Instance Editable」チェックボックスを選択しても同じ効果があります)。
Instance Editable(目のアイコン)で、変数をpublicに設定します。これにより、以下の2点が可能になります。
1. この変数を、他のブループリントで受信したり、編集したりできます。
2. 現在のマップ内に、このブループリントのインスタンスが複数ある場合、エディターで、インスタンスごとに変数の値を変えられます。
メインエディターに戻る前に、必ずブループリントをコンパイルし保存してください。BP_SetSwitchを、ViewportまたはWorld Outlinerで選択すると分かりますが、Switch Valueの変数がDetailsウィンドウに表示されるようになりました。ここで値をHurdle-Passに設定できます。
アーチでも同じことを繰り返します。BP_SetSwitchを、Content BrowserからViewportにドラッグし、ハードルの上に置いた時と同じように、アーチの下に調整して置きます。あとはSwitch ValueをArchway-Passに設定するだけです。
次は、赤の道と緑の道のボックストリガーです。これらのトリガーでは、別の処理を行います。単にそれぞれの道にスイッチを設定するのではなく、プレイヤーがどちらかの道に足を踏み入れたら、すぐにミッションが終了するようにします。それには新しいブループリントを作成する必要があります。
ボックストリガーをドラッグして持ってきたら、どちらかの道(私は赤)の上部全体を覆うように調整し、わずかに浮かせます。次にそれを使って、BP_SetSwitchの時と同じ手順で、新しいブループリントを作成します。ただし名前はBP_Pathにしてください。
Event Graph内で、2つの変数をつくります。
- 名前はNarrationEndとMissionCompleteにします。
- どちらもブール型の変数です。
- どちらの変数もpublicにするので、目のアイコンを押すか、Detailsパネルで「Instance Editable」チェックボックスにチェックを入れます。
これらの変数の目的は、名前にある通りです。ナレーションは終了したか?ミッションはすでに完了したか?最初に、ミッションの説明が終わる前にミッションが終了しないようにします。次に、ミッションが複数回も完了されることがないようにします。
それではブループリントをコンパイルし保存してください。ここで、Level Blueprintに戻ります。メインエディターのBlueprintsタブで「Open Level Blueprint」を選択すればアクセスできます。
この中でUnreal Engineにナレーションの終了を伝えますが、Narration Endの変数は別のブループリントにあるので、この変数に何らかの方法でアクセスする必要があります。
そこで、BranchのFalseの実行ピンからドラッグし、「Get All Actors Of Class」を検索し選択します。Actor Classフィールドで、先ほど作成したブループリントの名前であるBP_Pathを見つけます。次に、Out Actorsピンからドラッグし、「Get (a copy of)」を検索し選択します。これを繰り返し、「Get (a copy of)」をもう1つ作成します。1番目のGET関数の値は「0」、2番目のGET関数の値は「1」にします。
この2つの“GET”で、ゲーム内の2つのBP_Pathアクターである「赤の道」と「緑の道」を取得します。
この1つのブループリントで、「赤の道」と「緑の道」のアクターを複数回取得するので、その関数を作成しておくと便利です。「Get All Actors of Class」と2つの「GET」をまとめて選択して右クリックし、Collapse to Functionを選択します。My BlueprintウィンドウのFunctionsタブリストで、新しい関数の名前をGet Pathsに変えます。Get Paths関数をダブルクリックすると、そのEvent Graphを見ることができます。
この関数を使う前に、何カ所か編集します。まず、2つのGET関数の結果にアクセスするにはReturn Nodeが必要です。Event Graph内の任意の場所を右クリックし、 Add Return Nodeを検索し選択します。次にGet All Actors of Classノードの実行ピンと、Return Nodeの実行ピンをつなげます。最後に、青いノードを、2つのGET関数からReturn Nodeに向かってドラッグします。それにより、Return Nodeに、変数のスロットが新しく2つ作成されます。これらのピンの名前を編集するには、Return Nodeを選択し、Outputsタブで変数の名前を変更します。
最後に「Get Paths」ノードを選択します。Detailsウィンドウで、「Pure」のチェックボックスにチェックを入れます。
純粋関数(Pure Function)は、ステートやクラスのメンバーを一切変更しません。Actor変数を取得するだけで変更はしないので、この決まりを守れます。
「Get Paths」ブループリントを閉じて、Level BlueprintのEvent Graphに戻りましょう。Get Paths関数に、2つの青いPathピンが表示されています。1つ目からドラッグし、「Set Narration End」ノードを作成します。続いて、2つ目のPathでも同じことを繰り返します。すべての実行ピンを接続したあとの最終的な結果は次のようになります。
ここでの作業は以上です。このブループリントをコンパイルして保存し、BP_Pathブループリントに戻ります。BP_SetSwitchと同じように、Event ActorBeginOverlapを使います。このイベントの実行ピンを「Cast to PlayerController」関数へとドラッグし、続いて青い「Other Actor」ピンをCastのObjectピンへとドラッグします。
次は、ミッションの説明が終了したかどうかの確認です。NarrationEnd変数を、VariablesタブからEvent Graphにドラッグし、「Get NarrationEnd」を選択します。続いて「Cast to PlayerController」関数から実行ピンをBranch関数にドラッグします。NarrationEnd変数をBranchのConditionにつなげます。
これをもう一度繰り返しますが、今度はミッションが完了したかどうかの確認です。
これでブランチを設定できたので、続いてMissionComplete変数をTrueに設定し、プレイヤーが歩いた方の道をSwitch Valueに設定し、「Play_MissionResult」イベントをプレイヤーにポストします。
Set SwitchのSwitch Valueからpublic変数を作成した方法は覚えていますか?覚えていない場合は、BP_SetSwitchの時にどうしたかを確認してください。
必ずブループリントをコンパイルし保存してから、メインエディターに戻りましょう。最後に、Pathに移動し、Switchを「Path-Red」に設定します。さらにこのPathを複製し(Ctrl + W)、緑の道の上に収まるように調整したら、あとはこのSwitch Valueを「Path-Green」に設定するだけです。
以上です!テストして、ミッションの説明を聞いて、ミッションを実行してみましょう。緑と赤の道を両方とも試し、シナリオで適切なMission Result(ミッション結果)ダイアログが流れることを確認してください。
今のところ、これはゲームで問題なく実行できます。しかし問題があります。今、利用できるエンディングは、プレイヤーが「赤の道」を進んだ時と「緑の道」を進んだ時の2つだけです。Wwiseでは、他に3つのエンディングを設定しました。
これを解決するために、最初のナレーションが終わった後に、5秒のタイマーを設定します。ミッションが終了する前にタイマーが切れた場合は、ミッション結果をポストし、プレイヤーがどちらかの道に進んで再びミッションを完了することがないようにMission Completeの変数をTrueに設定します。
まず、Level Blueprintに戻ります。Narration End変数をTrueに設定したら、Delay関数でタイマーを開始させます。2つ目の「Set Narration End」の実行ピンを、Delay関数につなげます。
次に、すでにどちらかの道に進んでミッションを完了していないかどうかを、確認します。Get Paths関数を、Functionsリストからドラッグしてきます。そして、両方のPathピンからドラッグし、「Get Mission Complete」とします。
どちらのブール型Mission CompleteもTrueでなかった場合は、Mission Result(ミッション結果)イベントをポストします。これには、以下のように、「OR」ブール型ノードとBranchを使います。
Falseの実行ピンから、「Play_MissionResult」をプレイヤーにポストします。先ほどと同じように、「Post Event」関数のActorピンを、「Get Player Character」関数につなげます。
イベントをポストしたら、あとはMission Complete変数をTrueに設定するだけです。ここでもGet Paths関数を使い、今度はMission CompleteのGETではなくSETにします。
Level Blueprintの全体はこのようになるはずです。
それでは作業内容を保存し、テストしてみてください。5種類のシナリオを1つずつ試して、それぞれが正常に動作するかどうかを確認してみましょう。問題があれば、何か見落としがなかったかどうか、自分の作品をもう一度確認してみてください。すべて正常に動作したら、おめでとうございます!うまく機能するダイナミックなダイアログシステムの構築に成功しました。
コメント