ADXアンバサダーとして記事を書いておりますSigと申します。
この記事ではアンリアルエンジン5とサウンドミドルウェア「ADX for UE」を連携させ、ノベルゲームの台詞とボイスなどを紐づけ、スクリプトづくりを効率化するテクニックを紹介します。
ノベルゲームを制作する際、台詞とボイスの管理は非常に重要です。
多数のテキストと音声を扱うには、統一された規格での管理をしておくと安全です。
当記事ではUE5.5+「ADX LE UE SDK(2.01.00)」を使用します。
また、基本的にブループリントのみでの実装を行います。
ADX for UEはインディー向けの「LE版」であれば、無料で使用できます。
https://game.criware.jp/products/adx-le/
前提
「ADX for UE LE」を使用します。導入や簡単な使い方は以下の記事にあります。
ADX for UEの導入で、一歩上のサウンド表現を(導入編)
ADX for UEの導入で、一歩上のサウンド表現を(実践編)
なぜ台詞をデータテーブルで管理するの?
ノベルゲーム製作では、膨大な台詞・音声をまとめて管理する必要があります。
他にも、演出ごとに専用ロジックを作っていると処理が煩雑化してしまい、不具合の温床になるなどの懸念もあります。
これらを解決するために、台詞データを構造化し、スプレッドシートで管理 → UEに取り込み → 処理を実行 というフローを作るのが理想です。
データテーブルはデータを表として記述しますが、そのためにどのような情報を扱うかという「構造体」を作っておく必要があります。
構造体の設計例と役割
ノベルゲームにおける基本的な情報を扱うため、次のような構造体を構成してみましょう。
変数名 | 用途 |
---|---|
ID | 行の識別子、通し番号やイベント名など |
SpeakerName | 台詞における、話者名の表示に使用 |
DialogueText | 実際に表示する台詞テキスト |
CueName | Atom Sound Cueの名前(文字列) |
こういった構造体を元にデータテーブルを作れば、スプレッドシートで1行ずつイベントを記述できます。
通常ボイス用アセットなどはリファレンスを指定する関係上、外部のスプレッドシートで記述することは難しいですが、ADX for UEでは文字列からキュー名を指定して取得できる機能があるため、取り回しが効くようになっています。
構造体を作ってみましょう。
コンテンツドロワー(コンテンツブラウザ)を右クリックし、「Blueprint」→「Structure」を選択します。
名前をつけます。今回は「FScriptRow」としました。
ダブルクリックして開くと、構造体が持つ変数を確認・編集できます。
変数を追加し、次のようにしました。データテーブルに欲しい情報を登録していきます。変数の型を間違えないように注意!
作成した構造体をもとに、データテーブルアセットを作ります。
コンテンツドロワーで右クリックし、「Miscellaneous」→「Data Table」です。
データテーブルが扱う構造体には、先ほど作った「FScriptRow」を指定します。
分かりやすいよう名前をつけます。
データテーブルが作られ、編集できるようになりました。
……が、UE内のエディタで編集していくのはちょっと面倒なので、外部のスプレッドシートで記述してみましょう。
外部CSVからデータテーブルを生成する
制作フローにスプレッドシートを取り入れることで複数人での編集を簡単にできるほか、UEを触らないシナリオライターも直接の台詞編集が可能になります。
今回はGoogleスプレッドシートを利用します。Excelなどでも同様の手順で反映させることができます。
スプレッドシートを新規に作成します。
開きます。
シナリオの流れに沿ってコマンドや話者、テキスト内容、そして音声のキュー名を記述していきます。
コマンドは後ほど実装していきますが、文字列なのでバリエーションを作りやすいでしょう。
一通り書けたら、「ファイル」→「ダウンロード」→「csv」でcsv形式でエクスポートします。
コンテンツドロワーにドラッグ&ドロップしてインポートします。
インポート時にベースとなる構造体を選択します。
編集されたデータテーブルがインポートされました。
キュー名から音声アセットを取得する(Blueprint)
データテーブルにはサウンドアセットそのものではなく、文字列でCue名を記述しています。これにより、外部CSVでも安全に記述・編集が可能になります。
データテーブルに記述されたキュー名から、対象のキューを取得してみましょう。
データテーブルのデータを読み出すには、Get Data Table Rowノードを使用します。
これはデータテーブル内の行を指定して、構造体を出力するものです。
青いインプットピン「Data Table」を右クリックし、「Promote to Variable」を選択して変数化します。
これにより、シナリオや章ごとにスクリプトのスプレッドシートを分けることが可能になります。
変数名をつけます。
一度コンパイルして、デフォルト値に今回インポートしたデータテーブルを指定します。
Integer型の変数「CurrentScriptID」を作成します。これはこれから読み出す行を指定するための変数です。
同じように組んでいると、Row Name(行の名前)は0から始まるIDになっているはずです。
String型に変換し、読み出す行の名前として指定します。
Break FScriptRowノードを使い、構造体を分解して中身の変数を取り出します。
まず行うのが、Command名による処理の分岐です。「Talk」なら会話の表示、「PlayBGM」ならBGMの再生……といったように、異なる処理に分岐させます。
Commandが「Talk」であれば、新しいテキストを表示する関数を呼び出します。
今回は話者を表示する専用のレイアウト領域を作っていないので、文章の初めに表示し、そこから改行して台詞を表示するという形にします。
改行するためにAppend Stringノードを使用します。
台詞表示時に音声となるキューを読み出すため、変数「CurrentCueSheet」を作ります。型は「AtomCueSheet」です。
Get Sound Cue by Nameノードで、「CueName」の文字列をキュー名として取得します。
台詞が表示され、台詞が表示されるようになりました。
他のCommandの場合も、処理ごとにノードを配置します。「PlayBGM」などの場合も、キュー名を指定すれば同じように読み出すことができます。
外部でスクリプトを編集し、UE5で読み出せる環境をつくり、より簡単で安全なシナリオ作りができるようにしてみましょう。
データテーブルを活用し、台詞再生やBGM再生などのイベントをテンプレート化すれば、ライターとエンジニアが共同で扱える、柔軟な制作環境が実現できます。