『Saints Row』(2022年)のオーディオチームはプリプロダクション段階でシステム設計を開始した時、一部システムの動作を実世界に倣ってみようと考えました。これは単純にチーム体制を基に決めましたが、私たちの独自エンジンに実世界でのスキルを適用することができる実践的な開発者たちがメンバーにいました。例えばフィジックスプログラマーは元フライトシミュレータ制作者、車両デザイナーはエンジニアなど・・・彼らは自分たちの経験に基づいてシステムを構築してゆきました。私たちはこれを活用しようと思いました。実世界で実証済みのシステムばかりであり、機能するものはそのまま使おうと考えたのです。
例えば私たちの車両エンジンは本物の車両と同じように設定されています。実際にRPM値があり、ギア比、スロットル、サスペンション、さらにタイヤのすべりまでを考慮しており、イグニッションとシャットダウンと速度RTPCだけではありません(もちろんそれらもありますが)。ボートのプロペラが水中かどうかを示すRTPCまであります。
さらに車両の衝突は、各種の衝突を車両ごとに登録しました。例えば私が全速力で走行してNPC車両に垂直に突き当たった場合、私の車両が再生する音は正面衝突、NPCが再生する音はTボーンクラッシュです。使用したアセットの数は限られていましたが、一般的な車両衝突音の配列が数千万通りにもおよび、さらにスイートナーレイヤーとしてランダムな車両パーツの落下音や液体噴射音が加わります。
同じ理論をプロップ(小道具)衝突にも適用しており、例えば大きな空洞の木樽が金属柱にぶつかった時は、まさにその通りの音がします。さらに私のお気に入りの機能の1つが弾丸の衝撃と爆発で、Initial Delay機能を使用して音速で伝わります(これに気づいて意識した人はいないと思いますが)。
この理論をプロジェクト全体で貫き、各オーディオシステムにおいて手の込んだことを試す前に、私たちが知る限り現実の実践的な実装を検討しました。ここからが面白いのですが、私たちは次にラジオシステムの設計に着手しました。
『Saints Row』ラジオ局の略史
ラジオ局システムを設計することは、経験とタイミングの完璧な取り合わせでした。私はVolition入社前に中堅ラジオ局という熾烈な競争の場で経験を積み、最初はプロモーション、のちにCMのデザインや多少のエンジニアリングに携わり、次に放送スタッフとなりました。ラジオのしくみを隅から隅まで熟知しており、『Saints Row』プロジェクトではじめてゼロからオーディオシステムを全面的に担当することができました。
それまでの『Saints Row』タイトルではバックグランドでさまざまなクロック、タイマー、シークテーブルなどが絡み合い、数100もの表ファイルがフレームごとに互いにやり取りをしていました。その裏側はまるで蜘蛛の巣のようで、蜘蛛がくしゃみでもしようものなら崩壊しそうでした。プレイヤーに見える側では同じ局に合わせた車のラジオ同士で相互受粉が行われ、同期バグも見受けられましたが、とりあえずラジオと呼べる状態ではありました。
もっとうまくできるはずだと思い、現実世界を優先するという設計方針を思い出し、気合いを入れ、オーディオプログラマーのMike Naumovをオフィスに呼びました。
発端は「ラジオはラジオであるべき」というシンプルな想いでした。ゲーム中に送信機が点在し、受信機が走り回っています。両者を繋げ、各ラジオ要素が従うためのプレイリストロジックを設定すればよいだけです。
送信機
電波を受信するためには、何かを再生する必要がありました。ゲームワールドの原点の下にオブジェクトを配置し、まずは昔ながらのカントリーAPMトラックのRandom Containerを再生しました。これがやがてラジオ局Tumbleweedへと発展してゆきました。
バーチャルボイス設定を使用して、常に同期させることが私の主な責任でした。一方Mikeはラジオのダイヤル機能に取り掛かり、放送局の切り替えテストを開始できるよう、別のコンテナを持つ別のオブジェクトを追加しました。
受信機
次にラジオのスイッチを入れた時に、実際に放送が聞こえるようにする方法を考えました。最初にSpeaker Panning/3D Spatialization Mix機能でプレイヤーが選択したラジオ局を2Dに替え、それ以外は3Dのままにするという単純なRTPC設定を試しました。しかしNPCたちの車も同じ放送局にチャンネルを合わせた場合、音楽が二重化してしまうことを懸念しました。最終的にプレイヤー本人の受信機にPCまたはNPCをRTPCで割り当てて、基本的に同じことを行うという単純な解決策に落ち着きました。
これで稼働するラジオコンポーネントをすべての車両に搭載することができ、プレイヤーキャラクターのラジオとNPCのラジオを区別し、局を切り替える機能を提供しました。
独自開発したマルチポジションのエミッターツールを使用し(UnrealにあるAKのSet Multiple Positionsノードと似ています)、新しいゲームオブジェクトを作成せずにエミッターポジションを各ラジオコンポーネントに動的にアタッチし、音声やオブジェクト数をいじらずに、移動中の複数の車両で同じラジオ局を流すことができるようになりました。
ラジオ局
ラジオ放送の送信方法と受信方法が決まったところで、次はラジオ局の創設です。かつて実際のラジオ用プレイリストをScott Studioで設定し実行した経験から、今回のラジオシステムの心臓部にも同じ機能を復元すればよいと考えました。
こちらはグーグル検索で見つけた、2006年頃のラジオ自動化ソフトウェアScott Studios SS3のインターフェースのスクリーンショットです。
(出典: https://www.devabroadcast.com/dld.php?r=759)
ラジオ放送局のプログラマーはここであらかじめ番組の流れを定義し、コマーシャル、ニュース、DJトーク、天気予報、放送局IDなども個々の要素として含めることができ、放送スタッフは自動化されたプレイリストを流したり、時刻やリクエスト曲を挟んだりできます。
ゲームでこれを実現するために私たちは同じような要素のシステムでモジュラーシステムを構成し、デザイナーがあらかじめ順番を定義し、CMが連続しすぎる、アウトロのある曲の直後に次の曲のイントロが入る、2つのCMの間に放送局IDが入るなどがないよう、番組を編成できるようにしました。おまけにモジュール形式にしたことで、プレイヤー作のカスタムプレイリストへの扉が開けました。
こちらのテーブルエディターのスクリーンショットからも分かるように、言葉なしの要素の合間にNEWSCAST(ニュース)が散りばめられています。ゲームプレイのある部分を完了してニュースをアンロックできた場合に限り、再生可能な次のスロットでニュースを再生するというシステムになっています。ニュースで選手のアクションを取り上げるためです。Mikeがプログレッション担当チームと協力してくれたおかげで、この機能を簡単にセットアップでき、非常に助かりました。
楽曲
いくつかのInteractive Music機能を中心にここまでシステム全体を計画してきましたが、いよいよWwiseが威力を発揮する番です。各要素がモジュール化されているため、それぞれの再生Eventさえあれば充分です。これらの組み合わせを別のテーブルクラスでつくり、コードで選択します。以下の通り各曲は単なるSwitch Containerであり、フレーバーがその下にネスト化され、シーケンスを構成しています。
フレーバーを選択する際、そのラジオ局のオブジェクトにSwitchが設定され、曲のSwitch Containerのための再生Eventがポストされます。Exitキューをトランジションのタイムアウトとして設定することにより、どのDJも完璧に曲のタイミングに合わせることができます(これは特定のビートでしゃべりを終わらせるという意味で、すべてのオンエアパーソナリティが目指す自慢の技です)。
Exitキューは歌のはじまりを始動させるため、DJのトークは必ずそこでぴったり終わり、それを表しているのが下図のプレイヘッドの位置です:
アウトロにも同様の注意を払い、音楽が終わりはじめる頃にExitキューを出してDJのトークを開始させます。DJのボイスバスにサイドチェインコンプレッションも使い、音楽の方がDJより強い場合は音楽を突き抜けてDJが聞こえるようにしました。
Exitキューに加え、個々のトラックだけでなく各ラジオ要素が終了したことを、ラジオシステムに伝える方法が必要でした。カスタムキューを準備して具体的なラベルをつけ、コードが特定のAKコールバックを待ち受けるようにし、これがトリガーされた時に次の要素を選択・再生するよう、システムに指示できるようにしました。これによりエンジン側の処理が大幅に効率化され、要素間で非常に自然なクロスフェードとなり、実際のラジオDJが手動で次の要素を強制的に再生させたり、クロスフェードの時間をあらかじめ決めたりするようにできました。すべての要素に使うカスタムExitキューが同じであるため、循環するたびにコード側では1つのコールバックを待ち受けるだけでした。
結論
以上がすべてまとまると、いままで見てきた中で最もリアルなラジオ体験になったと感じました。同じ放送局を聴いている2台の車がすれ違った時は完全に同期しており、プレイヤーが好きな曲を流している車をハイジャックした時は、曲の全く同じ箇所でLPFとボリュームのオフセットが即座になくなります。チャンネルを回しながら最初の局に戻った時、再生されていた曲はプレイヤーの行動に影響を受けないであたかも放送され続けていたかのように聞こえ、実際にその通りなのです。
Wwiseの各種機能、当時の私のプロジェクト内の立場、現実世界の全く同じ分野における職務経験、さらにMikeのすばらしい仕事内容とパラダイムを書き換えようとする積極性などが、完璧に融合していなければ、私たちはおそらくまだクロックを稼働させ曲をシークしてから再生し、CPU予算に驚異的な負荷をかけていたと思います。さらに古いシステムのバグをすべて潰し、将来的にファンが改造するかもしれないことに備え、ラジオをできる限りモジュール化することもできました。全体的に非常に楽しく満足のゆく経験となり、大変誇りに思っています。
コメント