バージョン
Wwiseではほかの多くのゲームエンジンと同様に、プロジェクトの各種アセット管理に数値IDを用いています。WwiseがプロジェクトのアセットにアサインするIDには2種類あり、Wwise Authoringアプリケーションが使用するID(wa)と、Wwise Sound Engineが使用するID(wse)となります。プロジェクトをアップデートすると、Wwiseは新しいIDをアサインしたり、IDを更新したりします。これはバックグランドで行われ、一般的に作業メンバーに見せる必要がない部分です。ところが、あなたのプロジェクトがフィックスや拡張などの理由で継続的に更新されるゲームであれば、WwiseのアセットIDのアサイン方法や用途に関する知識が重要になります。いずれの場合も、ゲームの更新規模を最小限に抑えることが望まれます。どのようなWwiseプロジェクトでも一番数が多いのはオーディオアセット(.wemファイル)なので、更新するときはオーディオファイル数を制限した方が良いです。このためには、プロジェクトのオーディオアセットIDを変更せず再利用して、アセットを何度もパブリッシュする必要性を低減することが不可欠です。
WwiseがどのようにプロジェクトアセットにIDをつけていくのかを説明するために、以下の簡単なプロジェクトを例にとります。プロジェクトの中に、以下が入っています:
オーディオアセット Hello.wav が1つ
Soundオブジェクト Hello が1つで、その参照先は上記のオーディオアセット
このオーディオアセットの再生をトリガーするためにゲームが利用する、Playアクションの入った Play_Hello というEventオブジェクト
図: Play_Hello イベントと、ターゲットサウンドの Hello。
それでは、Default Work Unitの中身を見て、このSoundオブジェクトにWwiseが何をアサインしたのかを確認します。以下が、このSoundオブジェクトが、そのWork Unitファイル(.wwu)に記載されている様子です。このSoundオブジェクトの項目で、今回は無関係なものは、分かりやすさのために除外しました。
Wwiseが、Soundオブジェクトに対し、2つのID、つまりIDと、ShortIDを、アサインしたのが分かります。それでは、それぞれ詳しく見ていきます。
「ID」とは、このSoundオブジェクトのWwise Authoring IDのことで、ユニークなIDであると保証された128-bitのGUIDです。分かりやすくするために、ここでは単にGUIDと呼びます。Wwise Authoringは、ユニークIDであるGUIDを使います。これによって、以下のようなメリットがあります:
編集ソフトウェアで実行する必要のある様々な操作を、管理しやすい。
複数のチームメンバーが貢献するかもしれないプロジェクトを、管理しやすい。
ワークユニット間で、オブジェクトを参照しやすい。
Play_HelloというEventオブジェクトのWork Unitを見ると、これがHelloというSoundオブジェクトを参照していることが分かります。
ところがGUIDは、プロジェクトのアセット数を考慮すると、Wwise Sound Engineの中で使うには不便です。
ShortIDが、Work Unitの特定のオブジェクトにアサインされるもう一つのIDで、32-bitの整数です。あなたのプロジェクトの様々なSoundBankに保存されるのはこのIDだけで、Wwise Sound Engineによって使われます。分かりやすくするために、ここでは単にShortIDと呼びます。GUIDがプロジェクトの最初から最後まで1つのオブジェクトのユニークIDであるのに対し、ShortIDは、そのShortIDのスコープ(範囲)内に限り、このオブジェクトのユニークIDとなります。つまり、あるオブジェクトのShortIDがユニークIDとなるのは、そのShortIDと同じスコープ内のオブジェクトに対してだけです。ShortIDのスコープは、以下の通り3種類あります:
1. Explicit IDs - Sound EngineのSDKファンクション経由で アクセなできない オブジェクト
ユーザーコードを使って参照することができないオブジェクト(例 Actor-Mixerオブジェクト)です。このスコープ内のオブジェクトは、さらにオブジェクトタイプによって分けられます。そして、オブジェクトのShortIDは、それが所属するオブジェクトタイプ内に限ったユニークIDとなります。例えば、以下のようなオブジェクトタイプが該当します:
Actor-Mixerオブジェクト、Interactive Musicオブジェクト(Sound、Container)
Busオブジェクト(Bus、Aux Bus)
エフェクト
ShortIDは、オブジェクト作成時にアサインされるランダムな数字です。ランダム値なので、各オブジェクトのShortIDは、そのWork Unit内に、明示的に記録されます。
2. Implicit IDs - Sound EngineのSDKファンクション(Event、State、Switchなど)経由で アクセスできる オブジェクト。
これらのオブジェクトはSDKファンクションから名前で参照されることがあるので、これらのオブジェクトには特定のShortID値がアサインされます。ShortIDはオブジェクト名のハッシュから生成されます。このため、以下の特徴があります:
名前を付けた2つのオブジェクトが、同じ名前になることはありません。
名前を付けた2つのオブジェクトが、同じShortIDになることはありません。
前述のExplicit ShortIDと同様に、このスコープのオブジェクトもタイプ別に分かれています。例えば、以下のようなオブジェクトタイプが該当します:
Event
Switch
State
RTPCs
ShortIDはランダムに決まるのではなく、オブジェクト名から明示的に決まるので、プロジェクトのWork Unit内に記録されません。先ほどのPlay_Helloというイベントの、Work Unitのエントリーをもう一度見ると、Play_HelloイベントにShortIDエントリーがないことが分かります。
3. メディアアセット(.wemファイル)
すべてのメディアアセットに、ユニークなExplicit ShortIDが付けられます。これらはランダムな数字であり、Work Unit内に記録しておく必要があります。前述の例では、SoundのメディアをAudioFileSourceオブジェクト経由でトラッキングし、それにアサインされているIDは、MediaIDエントリー経由でトラッキングしています。
Wwise Authoringはオブジェクトが作成されると、その都度そのオブジェクトにShortIDをアサインするので、必ずユニークなIDとなります。ただ新アセットに貢献するチームメンバーが多数いる場合は、ShortIDが重複するリスクがあります。例えば、以下のような状況が考えられます:
あなたのプロジェクトにAというオブジェクトがあり、そのShortIDが 12345678 だとします。
チームのほかのメンバーが、別のWork Unitを作成しました。
新しいWork Unitは、あなたのプロジェクトのオブジェクトAが存在する前に作成されました。
新しいWork UnitにはオブジェクトBが入っていて、それは同じShortIDです。
新しいWork Unitが、プロジェクトに対して保存されました。
この場合、同じShortIDをもつオブジェクトが2つあり、ShortIDのコンフリクトが発生します。コンフリクトを解消するために、Wwiseがどちらかのオブジェクトに、新しいユニークなShortIDをアサインします。Wwiseはコンフリクトの原因であるオブジェクトに、新しいShortIDをアサインします。つまり、最初にロードされたオブジェクトはそのままのShortIDを維持し、そのあとににコンフリクトを発生させたオブジェクトのShortIDは変更されます。
とはいえ、すべてのアセットをロードした状態でWwiseに新しいオブジェクトを取り込んだ場合は、リスクがありません。ゲームにDLCがあるような場合は、そのプロジェクトに新アセットを取り込む時点で必ず、出荷済みのアセット(つまりプロジェクトのWork Unit)が存在し、ロードされている状態にしてください。こうすることで新アセットと、既存の出荷済みアセットで、絶対にコンフリクトが生じません。新しいアセットが、ほかの新アセットとコンフリクトを起こした場合は、新アセットをマージする時点でWwiseがコンフリクトを解消してくれます。
注: WwiseがShortIDのコンフリクトを解消するために、コンフリクトの対象であるオブジェクトのShortIDを変更すると、同時にSoundBank内のShortIDも変更されます。そのような場合は、SoundBankの再生成が必要となり、ログメッセージで表示されます。
Wwiseで、オブジェクトごとにShortIDをアサインし、そのオブジェクトをほかと区別する方法が確認できました。また、同じ考え方をメディアアセットにも適用できることも分かりました。一方メディアアセットには、ほかの種類のオブジェクトと大きな違いが1つあり、それは再利用できる点です。さて、さきほどの簡単なプロジェクトを更新してSoundオブジェクトをもう1つ作成してみましたが、これも Hello.wav を使うものとします。以下は、 Default Work Unit で両者のSoundオブジェクトに関係する部分です。分かりやすくするために、ここではメディアアセットのShortIDをMediaIDと呼んでいます。
どちらのSoundオブジェクトも、同じMediaIDが付与されています。これは、どちらのSoundオブジェクトも、全く同じメディアアセットを使っているからです。実際、ゲームに同じメディアアセットのコピーを複数入れて出荷するのは、無意味です。同じオーディオアセットのインスタンスが2つあったときに、両方とも全く同じ.wemファイルへとつながるのであれば、それを同一のオーディオアセットととらえます。つまり:
2つのインスタンスが、コンバージョン前に同一:
メディアアセットの変更は、Source Editor上で、コンバージョン前に行われた場合です。
ファイルの変更とは、例えばファイルのトリミングや、フェードの追加などを指します。
今回の例で、どちらのSoundオブジェクトも、ファイルが変更されていません。
2つのインスタンスが、コンバージョン後に同一:
Conversion Settingsは、Conversion Settings Editor上で編集できます。
今回の例で、どちらのSoundオブジェクトも、同じConversion Settingsを使います。
先ほどの事例では、 Hello.wav というオーディオアセットを見ると、どちらのSoundオブジェクトも同じMediaIDでした。それではプロジェクトを再編集し、 HelloAgain のコンバージョン設定を変えてみます。以下が、更新されたWork Unitです。先ほどと同様に、今回の説明に重要でない部分は省略してあります。
HelloAgain は、使うConversion Settingsが変わったので、別の .wemファイルにつながり、新しいMediaIDが付与されています。なお、新しいMediaIDを付与されたのが HelloAgain であり、 Hello でないことに注目してください。これは、 Hello のメディアアセットが変わっていないからです。
メディアアセットの作成や編集が行われると、Wwiseは必ずMediaIDを再確認します。Wwiseは、可能な限りMediaIDを変えないようにします。そして、変える必要があれば、作成されたアセットや編集されたアセットに対してだけ、新MediaIDをアサインします。
プロジェクトを完全にロードした状態で、編集作業をWwiseで行えば、変更されていないメディアアセットは今までと同じMediaIDを維持できるように、Wwiseが管理してくれます。ただしプロジェクトのMediaIDの一貫性を確保するために、プロジェクトチームが配慮するべき点が、ほかにもあります。
WwiseがMediaIDをアサインするとき、まず、メディアアセットのインスタンスをすべて確認し、同じコンバージョン後のメディアを要するインスタンスが2つ以上ある場合は、MediaIDを再利用します。そのために、そのメディアアセットの全インスタンスをWwiseが把握する必要があります。ところで、一部のインスタンスがWwiseにロードされていない場合はどうなるでしょう?1つのアセットインスタンスがロードされていないWork Unitであると、この状況になります。あるWork Unitがロードされると、WwiseはそのWork Unit内のすべてのMediaIDを再確認し、コンフリクトがないかを検証する必要があります。つまり、コンバージョン後の1つのメディアに対し、アサインされているユニークなMediaIDが1つだけであることを、Wwiseが確認する必要があるのです。ここで、2つの状況が考えられます。
プロジェクトをロードする
Wwiseは、すべてのWork Unitのロードが完了すると、すぐに、すべてのMediaIDを検証します。もしコンフリクトがあれば、どのMediaIDが維持されるのかを予測する方法がありません。これは、例えば複数のチームメンバーたちが、新しいWork Unitを複数、プロジェクトに取り込んだときに起きます。例えば:
チームメンバーNo.1が、 NewWorkUnit1 と、 Example.wav というメディアを、取り入れます。
チームメンバーNo.2が、 NewWorkUnit2 と、同じく Example.wav というメディアを、取り入れます。
プロジェクト全体を、2つの新Work Unitも含めたかたちで、Wwiseにロードします。
これによってMediaIDのコンフリクトが生じ、Wwiseが解消できます。ここでも考慮すべき状況は2つあります:
Example.wav は新しいアセットである場合。この場合、プロジェクトのほかの部分に全く影響しません。2つの新しいWork Unitのうち、WwiseがどちらかのMediaIDを維持するだけです。
Example.wav は既存アセットである場合。既存のWork Unitを、チームメンバーNo.1もNo.2もロードしたのであれば、Wwiseは既存のWork UnitのMediaIDを利用します。
1つのWork Unitをロードする
プロジェクトのWork Unitのうち、一部をプロジェクトにロードしていない状況も考えられます(詳しくは 「プロジェクトのWork Unitの、ロードとアンロード」 を参照してください)。前の例をもとに、以下のように条件を少し変えてみます:
Example.wav はすでにプロジェクト内に存在していて、 OldWorkUnit というWork Unitに入っています。
チームメンバーNo.1もNo.2も、それぞれ新しいWork Unitをつくり、そこに Example.wav を取り入れ、 OldWorkUnit はロードしません。
この場合、危険なのは、新しい2つのWork Unitは、 OldWorkUnit のMediaIDの情報がないまま、それぞれ別のMediaIDが付与されることです。このあとに OldWorkUnit をロードするとコンフリクトが生じ、Wwiseは、 NewWorkUnit1 、または NewWorkUnit2 のどちらかのMediaIDを維持させて、このコンフリクトを解消します。ところが OldWorkUnit は、すでに出荷済みのアセットの中に含まれているかもしれません。
どちらの状況でも、プロジェクトのアサイン済みのMediaIDを、1人のチームメンバーが間違えて変えてしまう可能性が充分あります。これを避けるためには、以下のようなワークフローをとると有効です:
WwiseがMediaIDを正しくアサインするには、プロジェクト全体のMediaIDの割り当て情報が必要です。前節でみたとおり、1つでもロードされていないWork Unitがあると情報が不足してしまいます。これを回避するために、WwiseにはプロジェクトのMediaIDの割り当てを1つのファイルで管理する方法があります。この、1つのファイルでMediaIDを管理する、というワークフローを紹介します:
MediaIDをWork Unit内に格納するのをやめます。
プロジェクトのMediaIDをすべて、"project-name.mediaid" という名前の別ファイルに入れ、それをプロジェクトのメインファイル "project-name.wproj" の横に保存しておきます。
WwiseでMediaIDをどのように管理するか(Work Unitで、または1つのファイルで)を選択するには、WwiseConsole.exeで、以下の引数を使います:
move-media-ids-to-single-file: 従来の "MediaIDs in Work Units" のワークフローから、1つのファイルで管理するワークフローに変えます。プロジェクト全体をコマンドラインからロードし、.mediaidファイルを生成し、Work UnitファイルからMediaIDの記載を削除する操作です。
move-media-ids-to-work-units: 1つのファイルで管理するワークフローから、従来の "MediaIDs in Work Units" のワークフローに変えます。プロジェクト全体をコマンドラインからロードし、MediaIDを.mediaidファイルから該当Work Unitファイルに移動し、.mediaidファイルを削除する操作です。
update-media-ids-in-single-file: .mediaidファイルの内容を更新します。プロジェクト全体をコマンドラインからロードしてから、更新されたMediaIDを.mediaidファイルに書き込みます。
それでは先ほどのプロジェクト例である WwiseIDs で、以下のコマンドを発行し、MediaIDを1つのファイルに移動させてください:
WwiseConsole move-media-ids-to-single-file WwiseIDs
以下が、 WwiseIDs.mediaid の中身です。
このプロジェクト例も、メディアアセットはHello.wavだけで、2つのオーディオソースインスタンスがあります。Hello.wavの各インスタンスに関しては、以下のとおりです:
インスタンスの記載は、そのオーディオソースのGUID (Authoring ID) で示されています。
このインスタンスに、MediaIDがアサインされます。
インスタンスには、MediaIDをアサインした時点で、このインスタンスが使ったConversion Settingsを示す、ハッシュ値があります。
MediaIDファイルは、Work Unitがロードされたあとのプロジェクトロード中に、ロードされます。MediaIDファイルは、どのWork Unitをロードしたかに関係なく、ロードされます。MediaIDファイルをロードするとオーディオファイルのConversion Settingsの各インスタンスをハッシュし、それをファイルのハッシュと比較します。もしハッシュが一致しないと必要に応じて、このインスタンスに新しいMediaIDがアサインされ、このとき、前節で説明したのと同じルールが適用されます。いったんプロジェクトをロードすると、ロード済みのWork Unitからくるインスタンスはすべて、 正規の MediaIDが付与された状態となります。ただし、あとからWork Unitを追加すると、MediaIDの再確認が行われます。
MediaIDファイルは、マイルストーンごとにあなたのWwiseプロジェクトを同期するために利用できます。マイルストーンのたびに、WwiseプロジェクトのMediaIDファイルが WwiseConsole.exe update-media-ids-in-single-file で更新され、MediaIDファイルは 最新のマイルストーン のものです。更新されたMediaIDファイルで、プロジェクト全体が、次の新しいマイルストーンのためにタグ付けされます。
チームで協力しながらWwiseプロジェクトの作業をするうえで、メディアアセットのIDをどのように管理するかは、チームやプロジェクトの大きさと、対象範囲によって、変わってきます。
少人数のチームで小規模のプロジェクトを完成させる場合は、各メンバーが、Wwiseプロジェクト全体をロードしてから作業すれば、それほど問題はありません。また、MediaIDのコンフリクトは、プロジェクトのバージョン管理ソフト上で管理すれば防止できます。バージョン管理ソフトは、拡張計画のあるプロジェクトでは必須です。リリースごとに、バージョン管理ソフトでプロジェクトを一度ロックすることで、出荷済みのアセットをそのままの状態で確実に維持できます。
一方、大規模なプロジェクトのため多数の関係者が作業して新しいWork Unitを同時に出すような場合は、より確実な管理が必要です。新しいWork Unitを各担当者が開発することは許容できますが、その場合は各チームメンバーがWwiseプロジェクト全体をロードした状態で開発するべきで、また新しいWork Unitをプロジェクトに入れる際は、1個ずつ行うべきです。この場合、プロジェクトのMediaID管理を1つのファイルで行うのも、1つの方法です。