『PRINCIPLES(プリンシプルズ)』とは
PRINCIPLESはiPhone/Androidなどのモバイルゲームにむけた技術研究として、Unityの軽量レンダリングシステムであるURPを中心として、消費電力やマシン負荷を抑えながらも高品質なグラフィック表現を実現したプレイアブルな技術デモです。
技術デモなのでゲームプレイはコンパクトで謎の洞窟を探検する5分程度のアドベンチャーゲームが楽しめます。それにあわせて開発チームも非常にコンパクトでありながらフォトリアルなグラフィックを目指して開発を行いました。そしてゲームオーディオもそれにあわせた低負荷でも豊かな表現をめざしてデザインしました。
サウンドデザインがめざしたもの
『PRINCIPLES』はゲーム内のテキストなどが存在しないため、プレイヤーに状況や目的をグラフィックとオーディオで説明する必要がありました。そこで私は、すごく大雑把にいうならば『なにか音のするほうに向かってみよう』と思ってもらえるようにデザインしました。そのためにWwiseの空間オーディオ機能をフルに活用して製作し、またUnityインテグレーションで提供されている機能を活用することでコーディングではなくサウンドデザインに充てる時間をたっぷりとるようにしました。
具体的には、普通よりもリスナーコーンを狭くしたり、配置する環境音がいろいろな方向から聞こえすぎないように配置をうまく調整しました。そういった場合にはWwiseのProfilerが、目と耳で直感的に配置を調整する助けとなりました。
AkAmbientとSoundSeedAirをつかった風音表現
ゲームを開始してすぐにプレイヤーが目標とする音は風の音です。洞窟の奥から吹き込む風の音がすることで奥に広い空間があることを期待させることができます。奥から聞こえる風の音をたどるようにすすむ体験を表現したかったのでLargeModeのAkAmbientを洞窟に沿っていくつか配置しました。
プレイヤーの移動経路上に配置する線音源はサウンドデザインにおいて悩ましい問題をいくつも抱えていますが(UnityのAudioSourceでは動的に音源を動かすスクリプトを書いたりします)、AkAmbientのLargeModeはその問題への大きな助けとなってくれました。
また、洞窟を吹き抜ける複雑な風音を表現するためには非常に長いループ時間の自然音を使うことがコストは高いものの一番簡単な解決方法ですが、今回はSoundSeedAirを使うことで解決してみました。
まず、3種類の収録された風音をランダムにならすRandomContainerを作ります。このContainerは10秒程度の3種類の風音をランダムな順番で鳴らし続けます。これで最低でも周期が30秒程度のループ音源をつくることができます。ランダムのおかげで実際にはもっと長いループにすることが可能です。
そこにさらにSoundSeedAir Windをつかった長いdurationの音を混ぜ込みます。SoundSeedAir Wind単体でも周期の長い変化のある風音を作り出すことは可能ですが、そこに収録されたランダムな風音を混ぜ込むと自然のような複雑な音を簡単に作り出すことが可能となります。
Wwise Reflectの活用
プレイヤーが最初に入るのは狭い坑道です。この狭さを表現するためにWwise Reflectを活用しました。AkRoomでSmall Room系などの深くて短めのリバーブを使用することでも狭い空間を表現することは可能ですが、やりすぎると音がこもってしまいます。そこでWwise Reflectの反射音を補助的に追加することにしました。Wwise Reflectによって初期反射が追加されると、プレイヤーの足音がすぐ近くの壁に反射して聞こえます。リバーブ=残響による空間表現では大まかな広さがわかるのに対して、反射音では「すぐ近くに壁があるぞ」と感じることができます。
ただ、Wwise Reflectだけでリアルな音響を作ろうとするとグラフィックのレイトレーシング手法と同じくとても計算負荷が高くなってしまいます。残念ながらモバイルゲームではCPUもメモリもハイエンドなゲーミングPCほど余裕があるわけではないので、Reflectを使うのは躊躇してしまいます。そこで今回私はReflectを使うのにルールを設けました。「Reflectはプレイヤーに壁の位置を感じさせるためだけに使う」ということです。
まずReflectのorderを1にしました。1回の反射で十分に効果が体感できる場面でのみ使用することにしました。次にReflectが刺さったBusにSendする音をしっかり吟味しました。VoiceVolumeが大きく残響成分の比率が少なくなるような音はSendせず、アタック感が強く短い音声のものだけをSendするようにしました。そして最後に部屋の形状を極力シンプルにモデリングするようにしました。これは反射面の数を減らすことで計算を簡単にする目的と、1回の反射でも十分に効果を感じられる場所を見極めるためでした。
最終的に8つのBoxとそれらを連結するPortalだけになりました。シンプルな構成ですが十分に空間の狭さを表現できたと感じています。
ProBuilderをAkRoomに活用する
AkRoomの形状を検討する際にはUnity ProBuilderを活用しました。背景アーティストに依頼する手法や、背景モデルをポリゴンリダクションするなどの手法もあります。しかし形状の複雑さや広さと、AkRoomやReflectのパラメータは同時に調整したほうが効率がよいと考えました。そこでProBuilderを使って形状の調整とパラメータの調整を同時に行いました。Unity ProbuilderはUnityの比較的新しい機能で、ビルドインではないためPackage Managerから追加する必要があります。無料のパッケージでレベルデザインなどにも便利なので導入をおすすめします。
ProBuilderではいろいろなことができますが、サウンドデザインにおいてはそれほど難しいことを覚える必要はありません。
まず、ステージを上から見下ろすようにカメラを調整し、ProBuilderのWindowでnew poly shapeを選択し、ステージのモデルを囲むように頂点を配置します。反射回数を少なくする場合、あまり複雑にする必要はありません。配置したらExtrusionでステージの高さより少し高くなるくらいまで引き伸ばします。あとはProBuilder WindowからExportすればそのままAkRoomのMeshとして使用することができます。ProBuilderモデルをMeshとは別に保存しておけば後からの調整も簡単です。
ステージのモデルはゲームデザイン的観点から部屋が区切られていますが、サウンドデザイン的観点から考える部屋の区切りがそれとは異なる場合はよくあります。壁の材質や、Portalの位置にあわせてサウンドデザイナーがAkRoomをモデリングできる状態にしておくとよりよい演出の助けとなるでしょう。
ReaWwiseを使った効率的な足音作成フロー
PRINCIPLESでは砂地や板の足場などで足音が変化します。ゲーム開発が進むにつれて足場の材質が増えたり、あるいは作った足音をあとから調整するという作業を効率よくすすめるために、ReaWwiseを活用しました。Reaper上にプレイヤー用のトラックを作成し、サブトラックに各材質用のサブトラックを作成します。サブトラックには1秒ごとのリージョンを8つ作ります。
次にRegion RenderMatrixで各サブトラック×8リージョンを”$project_$parent_$track_$region”マクロで出力するように設定しておきます。そして実際の足音などはその下に作ったTrackで作成していきます。こうすると”ply_feet_mud_01”のような各材質とバリエーションにあわせたファイルが簡単に作れます。
今まではこの後にWwise上でSwitchコンテナを作成するといったフローが必要だったのですが、ReaWwiseの登場によってフローが大幅に改善されました。なんとここでReaWwiseを起動してTransfer to Wwiseしてあげるだけで実装が完了してしまいます。あとはWwise側に移動してPlayイベントを作成するだけです。
PRINCIPLESでは最初にUVI Walkerを使って足音を作りました。Walkerのようなサンプラーシンセを使うと簡単に材質のバリエーションを作成することができます。そしてゲーム開発にあわせて草のすれる音や泥しぶきなどのテクスチャを増やしたり、収録したフォーリーに差し替えることを何度も行いました。
ReaWwiseを使ってReperとWwiseを連携させておけば既存のSoundSFXを置き換えることが簡単になります。最初にサンプラーで作った音を収録した音声に差し替える、あるいはトラックを増やしてテクスチャを追加した場合も簡単にReplaceしてくれます。
ReaWwiseはオープンソース(https://github.com/audiokinetic/ReaWwise)で公開されている機能なのでReaScriptの設定さえすればすぐに使うことができます。
より効率的なReaperプロジェクトの作り方などはStrataを参考にすると良いでしょう。無料のサンプルプロジェクトを見るだけでも学ぶべきところは沢山ありました。
足音のシステムを頻繁に作る人はテンプレートファイルを作っておいたり、ReaScriptを使ってReaperの構築とWAAPIによるWwise側の設定を同時にするスクリプトを作っておくのもおすすめです。
ChatGPTでWAAPIやReaScriptを書いてもらうことも可能なので挑戦してみるのもよいでしょう。コードはエレガントさに欠け、少し手直しが必要ですが、それでも単純な作業の繰り返しをあっという間に完了することが可能です。
破壊音の表現
プレイヤーは探検の途中で魔法の道具を手に入れ、それにより邪魔なものを吹き飛ばして破壊できるようになります。ここではいくつかWwiseの機能を組み合わせて演出を作り上げました。最初にImpacter-Pluginをつかって表現を探りました。Impacterは破壊音をグラニュラ化し、重さや位置などのランダムパラメータでそれを変化させてくれるので多彩なバリエーションを簡単につくることができます。
ですが、作っているうちに衝撃(Impact)と破壊(Body)の2段階ではなく、衝撃・破壊・余波の3段階で調整したほうがイメージしている音に近づけられると感じました。最終的に木に対する衝撃音、板が割れる破壊音、破片になった木箱が散らばる音を複数発音するEventになりました。
それぞれ4音ほどから構成されるRandomContainerを4種類、それぞれを2〜3個同時に発音することでイメージどおりの変化にとんだ破壊音を表現することができました。
(images/wimpact.pn
また、この破壊アクションでは破壊のインパクトを強調するためのAuto Duckingにも少し工夫をしています。破壊音が再生されるとMusic BusがAuto Duckによって静かになりますが、実はこのAutoDuckingは破壊音が再生される直前にDuckingが開始します。これは破壊音ではなく、直前の魔法がチャージされる音のEventでこっそり再生されている耳鳴り音によってAuto Duckingが実行されているからです。映画やアニメなどで爆発シーンの直前に全体の音量をさげて爆発のインパクトを強める表現に着想をえたものです。
爆発や破壊の音そのものでDuckingするよりも音のアタックによる印象を強めることが可能で、また爆発音がSpatializeによって変化しても一定したAutoDuckを実現できるために演出の調整やデバッグが簡単になります。こういった隠れたテクニックやアイデアを簡単に組み込んで実験できるのもWwiseの柔軟なEventシステムの魅力です。
VFX Graphエフェクトとの連携
PRINCIPLESではUnityの新しいパーティクルシステムであるVFX Graphのエフェクトも多用されています。VFX Graphでは今までのParticle Systemよりも表現性が高まり、システム内部で複雑なタイミング制御が可能となりました。それにあわせてWwise Eventを実行するためには、VFX Graphのノードシステム内からWwiseにシグナルを送る仕組みが必要となります。私はエフェクトが再生されるタイミングに合わせてWwise Eventを実行するためにVFXOutputEventAbstractHandlerを継承したWwise用のコンポーネントを作成しました。
これはもっともシンプルな実装です。ですがこれだけでWwiseにeventのタイミングを伝えることは可能です。
エフェクトアーティストにこのノードとSpawnノードをつなぎ、イベントを識別するためのラベルを送るようにお願いしておきます(簡単なのでもちろん自分でやりました)。少し複雑なエフェクトならば、送られてきたラベルにあわせてWwise EventをPostするようにしておけば実装は完了です。
VFX GraphからはPostしたGameObjectの情報だけでなくeventAttrivuteを介して複雑な引数(たとえばパーティクルの色、爆発の大きさ)なども渡すことが可能なため、RTPCやSwitchなどと連携することでより凝った演出が可能となっていくことでしょう。
Ak Listener Distance Probe
最後に、利用しなかった機能についても少しだけお話ししておきます。WwiseのAkListenerDistanceProbeは使用を検討しましたが採用しませんでした。
AkListenerDistanceProbeはとても新しい機能で、AkAudioListenerの空間オーディオ計算の際にListenerとは別に指定したProbeの位置を参照して補間してくれる機能です。もっとも代表的な使い方としては、カメラにListenerを設置しキャラクターの頭にProbeを設置します。これによりThirdPersonなカメラをもったゲームにおいて、リスナーの位置をカメラにするかキャラクターの頭にするか悩まなくてよくなります。
PRINCIPLESはThirdPersonなゲームですのでこの機能がとてもマッチしているように考えられました。しかし、現状生まれたばかりのこの機能では下の画像のようにListenerとProbeが、異なるRoomやgame-defined aux sendsにある場合にどのように補間するかといった調整ができませんでした。
PRINCIPLESではRoomごとのパラメータが大きく変化する部分があり、そこで違和感が生まれてしまったため、この機能を採用しませんでした。追従する際のfade timeなどでそこを調整することができていれば採用していた可能性はあります。また、最初からこれを使う前提でBusやRoomPotalを組むフローが構築されていけば問題は解消されていくかもしれません。
ただ、今までこれと同じような機能を自作していたりしたので、今後Wwise内にその機能がサポートされていくことはとても歓迎しています。
まとめ
フォトリアルなグラフィック表現のゲームにはより凝った表現のサウンドデザインが必要となります。プロジェクトの予算が潤沢で、優秀なサウンドプログラマーが協力してくれればよいのですが、小さなチームではそれを実現することは難しいです。Wwiseやゲームエンジンインテグレーションにはゲームサウンドにかかわる多くの人が工夫してきたアイデアがたくさん活かされているため、小さなチームでもそのアイデアを自分たちのゲームにもマッチするかすぐに試すことができます。
またReaWwiseをはじめとした、いままで各プロジェクトでサウンドプログラマーが頑張って作ってきたようなスクリプトなどもオープンソースとして公開されており、それらを使って効率のよい実装が可能となっています。ReaperやWwiseはスクリプトによる制御がサポートされており、それらは今のAIに書かせることができる簡単なコードで実行可能です。時間が限られた小さなチームではこういった効率化するための仕組みを利用し、空いた時間を新しい遊びを考えることに使うことが重要です。
「オーディオミドルウェアはリッチなゲームが使うもの」という思い込みは捨てて、小さなチームにこそオーディオミドルウェアを採用すべきだと私は思います。
©COLOPL, lnc.
コメント