会話システムの基礎

会話システムの基礎の基礎です。

会話システムとは言っておりますが、基礎の基礎ですからプレイヤーキャラクターの独り言状態であり、この状態では会話ではありませんけどね。

構造体: S_Dialogue

ブループリント > 構造体
名前: S_Dialogue
・新規作成。
・会話システムに必要な情報をまとめます。
「+変数を追加」をクリックして構造体を追加します。
■構造体
Name – String
Words – String *配列
FaceImage – テクスチャ2D

Nameは喋っているキャラクターの名前。
Wordsはキャラクターのセリフ。長い台詞は表示を分ける必要がありますから、配列にします。
Imageはキャラクターの顔画像。
このS_Dialogue(構造体)は、NPCなどのアクターブループリントが持ち、ウィジェットブループリント(UI)に渡すものです。

ウィジェットBP: W_Dialogue

ユーザーインターフェース > ウィジェットブループリント
親クラス: ユーザーウィジェット
名前: W_Dialogue
・新規作成。
・会話時に表示されるUIです。アクターブループリントからS_Dialogue(構造体)を受け取り、会話ウィンドウを開いて表示します。
デザイナー
最低限必要なものを使って簡単に作成。
こだわりの調整は後でやればいいですから、テキトーにパパッと配置して構いません。
細かい説明は省きます。
階層は、こういう具合。
  • キャンバスパネル: CanvasPanel_DialogueWindow
    会話ウィンドウそのものです。この中に画像やテキストを入れます。
    上記画像では白い点線。
  • 画像: Image_Face
    喋っているキャラクターの顔画像を表示します。
    Is Variableにチェックを入れて変数化しておく必要があります。
  • テキスト: Text_Name
    喋っているキャラクターの名前を表示します。
    Is Variableにチェックを入れて変数化しておく必要があります。
  • テキスト: Text_Text
    会話内容が表示されます。
    Is Variableにチェックを入れて変数化しておく必要があります。
  • 画像: Image_Button
    コントローラーのAボタンなどを表示します。
    Is Variableにチェックを入れて変数化しておく必要があります。
    アピアランス > Brush > Imageにボタン画像を選択。
    画像が無ければ画像ではなくTextにして「A」などでも構いません。
  • 背景ブラー
    これは無くても構いません。会話ウィンドウをボヤけやせるためのものです。会話ウィンドウ内全体に広げておきます。
    画像やテキストをボヤけさせないようにZoderを-1にします。奥に置くということです。
    ボヤけ具合はBlur Strengthで設定。今回は10.0にしました。
    背景ブラーではなく画像でも構いません。
イベントグラフ

■変数の作成
Words – String *配列
└複数のセリフを入れておく変数です。ゆえに配列。
WordIndex – Integer
└Wordsの配列の番号。Wordsは配列であり、複数のセリフが入っていますから、このIndexで指定して取り出します。
WordCount – Integer
└Wordsの文字数。「あいうえお」なら5文字という具合にカウントする。
MaxWordCount? – Boolean
└メッセージウィンドウ内にセリフが全て表示されたか?例えは10文字のセリフの全10文字が表示されたか?というフラグ。
TextDuration – Float
└文字の表示速度に使用します。

ノードを組む
カスタムイベント Start Wordsは会話ウィンドウに最初のセリフを表示させるためのものです。
カスタムイベント Next Wordsは会話ウィンドウに次のセリフを表示させるためのものです。

カスタムイベント Start Words
└インプット: Words – String *配列
・1文字ずつ表示していますから、Set Text (Text)の後にPlay Sound 2Dを配置すれば、ドラゴンクエストみたいにポポポ音を加えることもできます。
・現時点では未完成です。Next Wordsブランチの後にプレイヤーブループリントに終了を通知するノードが必要です。
ノードを組む
・S_Dialogueで設定した基本情報をセットします。
・会話発生時、最初に呼び出されるのがこのイベントです。

■カスタムイベント Set Dialogue Data
└インプット: S_Dialogue – S_Dialogue
・最初はカスタムイベントノードに「S Dialogue」と表示されています。右クリックして「構造体ピンを分割」をクリックして各項目に分割。

アクターBP: BP_Dialogue_Base

ブループリント クラス > アクター
名前: BP_Dialogue_Base
・新規作成。
・このブループリントは親です。NameやWordsを変数にしておくことにより、子ブループリントの「クラスのデフォルト」のデフォルト欄でキャラクターの名前やセリフを記載できます。
■変数の作成
W_DialogueRef – W_Dialogue(オブジェクト参照)
Name – String
Words – String *配列
FaceImage – テクスチャ2D(オブジェクト参照)
PromptStart – Boolean
└目玉アイコンを開ける(インスタンス編集可能)。

EndEvent – Boolean

PromptStartは即開始かどうか。これがTrueだと、このブループリントがスポーンされると同時に会話イベントが開始されます。Falseだと対象と接触することで会話イベント開始。

コンポーネントにBox Collisionを追加。

これに接触したら会話イベント発生させます。
ノードを組む
・アクターが持つ顔画像やセリフ内容をW_Dialogueに送って、Add to Viewportで会話ウィンドウを開きます。

Delay Until Next Tickを挟まないとAdd to Viewportが機能しないことがありました。こういうことはたまにあります。ノードの組み方にミスがないのに上手く機能しない場合、Delay Until Next Tickを挟むと解決することは少なくないです。
ノードを組む
・プレイヤーがBox Collisionにオーバーラップしたら会話イベントを開始します。

・PromptStartがTrueの場合は無効にしておきます。
・ちなみにCast to ***は使用しない方が良いです。ノードの注意書きにもありますが、負荷が大きくなります。Cast to ***が絶対に必要な時は使うしかないですが、他の方法があるならなるべく使わない方が良いです。
特に会話システムのように多く配置するアクターにCast to BP_Playerは推奨されません。
ノードを組む

ウィジェットを作成でW_Dialogueを選択し、変数にセット。
・Prompt StartがTrueであれば、即会話イベントを開始。
現時点ではWordsは1つしかありませんが、Words2やWord3を追加して、条件によってそれらをWordsにセットしてからStart Dialogueを起動して会話内容を変化させることもできます。
NameとFaceImegeも変更できますから、Words→Word2→Words3と順に進行して会話にすることもできます。

子アクターBP: BP_Dialogue_Test*

BP_Dialogue_Baseで右クリックして「子ブループリント クラスを作成します」を選択。
名前はBP_Dialogue_Test1。

BP_Dialogue_Test1を複製して、BP_Dialogue_Test2も作成。

BP_Dialogue_Test1

クラスのデフォルト > デフォルト のName、Words、FaceImegeを設定する。
複数のセリフがちゃんと表示されるかテストしたいですから、Wordsは+で増やして3配列エレメントにしておきます。セリフをここに記入。

Test1は即開始するイベントにしますのでPrompt Startにチェックを入れる。

BP_Dialogue_Test2

同じようにName、Words、FaceImegeを設定する。

こちらは接触して開始にしたいですから、Prompt Startにはチェックを入れません。

ブループリントインターフェース: BPI_Player

ブループリント > ブループリントインターフェース
名前: BPI_Player
・新規作成。
・これはウィジェットブループリントからプレイヤーキャラクターへイベントを繋ぐために使います。
■関数を作成
BPI_Dialogue
├インプット: W_Dialogue – W_Dialogue(オブジェクト参照)
└インプット: EndDialogue – Boolean

ウィジェットBP: W_Dialogue

ブループリントインターフェースを作成しましたから、W_Dialogueを完成させられます。

ノードを組む

Get Player CharacerからBPI_Dialogueを配置して、End Dialogueにチェックを入れます。
・ちなみに終了の通知はイベントディスパッチャーでも可能ですが、今回はブループリントインターフェースを使っています。

ノードを組む

・W_Dialogueが開いた時点で、プレイヤーキャラクターに情報を送っておきます。
・これは終了の通知ではありませんので、End Dialogueにはチェックを入れません。
・BPI_Dialogueのインプットを追加することで様々な情報をプレイヤーに送れますから拡張性があります。

プレイヤーBP: BP_Player

今回はBP_ThirdPersonCharacterを使っています。

まずブループリントインターフェースを実装します。
クラス設定 > インターフェース > 実装インターフェースに「追加」。BPI_Playerを選択。

実装されるとマイブループリントウィンドウにインターフェースが追加されています。

このBPI_Dialogueをダブルクリックすると、イベントグラフにイベント BPI Dialogueが配置されます。これはW_Dialogueに配置したBPI_Dialogueから起動するものです。

ノードを組む

・現時点では、プレイヤーキャラクターの停止と歩行のみの処理です。BPI_Dialogueのインプットを増やすことにより、様々な拡張が可能。
ノードを組む

・本来ならボタン入力のノードは、入力 > 入力アクションから作成するべきです。今回はテストのため簡易的なノードを使っています。キーボードのEをメッセージ送りボタンにしています。

テストプレイ

まずBP_Dialogue_Test1をLevelに配置。
これは即開始するイベントですから、どこに配置してもゲームスタート時に開始されます。
オープニングイベントという感じです。

BP_Dialogue_Test2をLevelに配置。
これはプレイヤーキャラクターが接触すると開始するイベントですから、プレイヤーが接触できる場所に配置しましょう。

セリフが全表示されるとボタンアイコンが表示され、ボタンを押すと次のセリフが表示されます。
セリフを表示中にボタンを押すと、セリフが一括表示されます。

テストプレイすると、すぐにBP_Dialogue_Test1の会話イベントが発生。
それが終了後、BP_Dialogue_Test2に接触すると会話イベントが発生。

今回はBP_Dialogue_Test1を最初から配置していますが、クラスからアクタをスポーンしますのノードを使い、例えばボスを倒した時にスポーンさせて会話イベントを開始できます。
敵のApply Damageから繋げて、敵のHPが一定値以下になったら会話イベントなんてことも自由自在です。

BP_Dialogue_Test2のコンポーネントにスケルタルメッシュを追加して人のメッシュを入れておけば、人との会話っぽくなります。
今回は単純接触での会話イベントですが、ボタンで開始するような変更も可能。

基礎の基礎

今回の会話システムは基礎の基礎であり、ここから拡張して複雑なシステムにすることができます。
会話中に選択肢を入れたり、イベントの進行状況によって会話内容を変えたり、サウンドノベルみたいに画面いっぱいに一枚絵を表示しながら会話したり。

  1. アクターブループリントがS_Dialogue(構造体)を持つ。
    会話イベントの開始は、このアクターブループリントから。
  2. 会話イベントが開始されると、アクターブループリントが持つS_Dialogue(構造体)の情報がW_Dialogue(UI)に渡される。
    W_Dialogue(UI)がそれらを表示。
  3. 会話イベント中にプレイヤーの行動を制限したり、ボタンで会話を進めさせるために、W_Dialogue(UI)とプレイヤーBPをインターフェースで連携してコントロール。

全体の流れを理解しておけば、拡張も難しくありません。

コメント

タイトルとURLをコピーしました