バージョン

menu_open
Wwise SDK 2019.1.11
Wwise バンク管理サンプル

ゲーム内でどのようにバンクを管理するかを決定する前に、次のドキュメントに慎重に目を通すことを強くお勧めします。

さまざまなバンク管理メソッドを理解する

イントロダクション

可能な限り柔軟性を保ち、ほとんどすべてのタイプのゲームの要件を満たせるよう、Wwise はゲーム内でバンクを管理するための新しいアプローチを導入しています。この新しいアプローチは、元のメソッドの有用性を無効にせずに更なる制御力と柔軟性を与えてくれるので、ゲームの要件をよりよく管理できるようになります。

既存の従来のメソッドに比べ、3つの主な改善点があります:

  • SoundBankはイベントのみでなく、構造的なコンテンツ(サウンド、コンテナ、エクターミキサーな)、ワークユニット、およびフォルダーを含めることができます。
  • バンクにどのようなタイプの情報が含まれるかを決定することができます。つまり、バンクにメディア、構造データ、イベントコンテンツを単体で、または、この3つを任意に組み合わせたものを入れることが可能です。例えば、特定のイベントと関連付けられたメディアのみを含むバンクを作ることができます。
  • サウンドバンクから特定のアイテムを含めたり除外したりすることができます。

このアプローチの主な利点は、メディアコンテンツを複数のメモリバンクに分割できることです。 例えば、単一のイベントを使用して、ゲーム全体のためのミュージックが開始したとします。従来のメソッドでは、バンクに当該イベントを追加することにより、ゲームの終了時にのみ再生する曲のためのプリフェッチを含めた、すべての対応するメモリ内サウンドとプリフェッチされたメディアが自動的に追加されます。ゲーム全体のための全メディアを格納することは、非常に非効率的だと思われます。一方、新しいアプローチでは、ミュージックメディアを複数のバンクに分割し、サウンドが再生される可能性がある場合にのみロードすることにより、メモリをより効率よく管理することができます。

また、メディアを複数のバンクに分割することにより、ロードされるメディアに優先順位をつけることができます。例えば、メモリに制限がある環境では、最も重要なメディアのみをロードしたいでしょう。非クリティカルなメディアは、十分な空き領域があった場合にのみメモリにロードされる別のバンクに格納しておくことができます。従来では、クリティカルおよび非クリティカルなメディアファイルの両方が同じバンクに含まれていました。バンクが大きすぎてメモリにロードできないと、クリティカルなものも含めていずれのサウンドも再生することができませんでした。

さまざまなバンク管理メソッド

以下のセクションでは、バンクを生成し、これをゲームに統合するために使用できるさまざまなメソッドについて説明します。単一ゲーム内では、1つのメソッドまたは異なるメソッドを組み合わせて使用することができます。全てのゲームは異なるため、ゲームの特定の要件に応じて(1つまたは複数の)メソッドを選択します。

バンクを作成する時に行う選択は、ゲーム内でオーディオアセットを管理するのに要求される作業量に大きな影響を与え、ゲームのパフォーマンスに直接影響を与えます。サウンドデザイナーとオーディオプログラマーの両方が、このドキュメントを慎重に確認し、利用できる可能性を認識しておくことを強くお勧めします。共同作業することで、ゲームの特定のニーズを満たす戦略を考え出すことができるはずです。いずれのソリューションも機能しますが、メモリ使用量、I/O アクセス、ゲームへの統合の容易さなどを考慮して戦略を選択する必要があるということを覚えておいてください。どのメソッドにも利点と欠点があるので、ほとんどの状況では、メモリ使用量と統合の容易さのバランスが問題となるでしょう。

メソッドNo.1:「オールインワン」バンク

このメソッドを使用する場合、すべてのイベントコンテンツ、サウンド構造データ、メディアファイルは1つのバンクに格納され、同時にメモリへロードされます。

このメソッドは以下の場合に適用可能です:

  • ゲームのオーディオアセット量に制限がある。
  • ゲームに空きメモリが十分ある。

もちろん、ほとんどのゲームには、一般的に無駄なメモリがありませんが、このテクニックには非常に使いやすく維持が簡単であるという大きな利点があります。Wwiseプロジェクト全体を最小限の時間でまるごとゲームに統合する場合には、このテクニックを使用することができます。

メソッドの実行方法:

Wwise 側

  1. サウンドバンクを1つ作成し、適切な名前をつけます。
  2. バンクを SoundBank Editor にロードし、"Add" タブに以下のアイテムをドラッグします:
    • "\Actor-Mixer Hierarchy\Default Work Unit"
    • "\Events\Default Work Unit"
    • "\Interactive Music Hierarchy\Default Work Unit" (インタラクティブミュージック使用の場合のみ必要)
    • “\Dynamic Dialogue\Default Work Unit”(ただし、ダイナミックダイアログを使う場合のみ)
      注釈: デフォルトで、Event(イベント)、Structure(構造)、Media(メディア)の各列のチェックボックスが、全て選択されます。このメソッドでは、すべてを1つのバンクに含めるので、これは適切です。

      Tip: 個々のプロジェクト要素ではなくワークユニット全体を1つのバンクに追加することの利点は、ワークユニットのコンテンツに加えられた変更を反映するためにバンクの再編集をする必要がないことです。これは、Wwiseがサウンドバンク内の要素とプロジェクト内の要素間にアクティブなリンクを維持するためです。プロジェクト内のワークユニットに変更が加えられると、サウンドバンクも自動的に更新されます。このアプローチを使用する場合、Generate ボタンをクリックするだけで、サウンドバンクの新規セットを生成することができます。
      注釈: 新しいプロジェクトには、デフォルトのワークユニットのみがあります。新たにワークユニットが作成された場合には、これらのワークユニットを必要に応じてバンクに追加しなければなりません。
  3. サウンドバンクにすべてのワークユニットが追加されると、サウンドバンクを生成し、生成されたバンクフォルダをゲームアプリケーションにコピーすることができます。

ゲーム側

今回の例のゲームのサウンドバンクは1つだけなので、ゲームを初期化する時にこれをロードするだけです。もちろん、サウンドエンジンがまず正常に初期化されている必要があります。

...
// Initialize the sound engine here.
...
// Load the Init bank and the "All in one" bank.
AkBankID bankID; // not used in this sample.
AKRESULT eResult = AK::SoundEngine::LoadBank( L"Init.bnk", AK_DEFAULT_POOL_ID, bankID );
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"MyAllInOneBank.bnk", AK_DEFAULT_POOL_ID, bankID );
}
...

このメソッドに関する補足事項

長所:

  • サウンドデザイナーの立場から見て、最も簡単なバンクコンテンツの維持管理方法である。
  • ゲームは常に同じバンクをロードするため、バンクのコンテンツを変更する場合にゲームを再コンパイルする必要がない。
  • バンクのゲーム内ロードとアンロードが簡単である。
  • 使用可能なサウンドのゲーム内追跡を必要としない。

短所:

  • ゲーム全体のための全イベント、構造体およびメモリ内メディアが常時ロードされるため、メモリの使用が非効率的である。
Tip: このメソッドは、迅速簡単にオーディオをゲームに統合するための良い方法ですが、ゲームのメモリをより効率的に使用するメソッドへの切り替えは、プロジェクトの最終段階まで先延ばしにしないようにしてください。

メソッド2:複数の完成バンク

このメソッドは以下の場合に適用可能です:

  • ゲームまたはそのオーディオコンテンツを複数のセクションに分割することができる。

このメソッドは、すべての再生可能サウンドが、プレイヤーのゲーム内での現在位置によって駆動されるシングルプレイヤーゲームに適しています。オーディオコンテンツを複数のバンクに分割することで、1つ目のメソッドより効率的にメモリを管理することができ、さらにゲームへのオーディオ統合も比較的簡単にできます。

メソッドの実行方法:

まず、バンクを分割する方法を決定する必要があります。 例えば、次のようなバンクの分割が可能です:

  • ゲームのどの時点でも発生する可能性のあるすべてのイベントを含んだ汎用バンク1つ。このバンクは常にメモリへロードされます。
  • レベルまたは環境ごとにバンク1つ。メインキャラクターの実際の位置に依存するサウンド用。
  • 場合により、各ゲームの要件に応じていくつかの追加的なバンク。

Wwise 側

  1. ゲームに必要なバンクを作成し、例えば、"CommonEvents"、"Level_1"、"Level_2" や "Level_3" など、適切な名前をつけます。
  2. イベントを Wwise 内フォルダにグループ分けします。バンクごとに1つのフォルダを作成し、各フォルダを対応するバンクにドラッグします。サウンドバンクにフォルダを追加することで、新しいイベントがプロジェクトに追加されるたびにサウンドバンクのコンテンツを編集する必要がなくなります。フォルダのコンテンツに変更が加えられると、サウンドバンクが自動的に更新されます。
  3. すべてのイベントをそれぞれのバンクに追加します。このステップは、元のフォルダから外れたイベントがあり、これらを追加する場合にのみ必要です。1つのイベントが複数のバンクに含められる必要がある場合は、そのようにします。
  4. バンクを生成し、生成されたバンクフォルダをゲームアプリケーションに追加する。

ゲーム側

ゲーム側では、適切なタイミングで適切なバンクをロードします。例えば、ゲームの開始時に汎用バンクをロードし、プレイヤーのゲーム内での実際の位置によって他のバンクをロードすることができます。ゲームによっては、レベル間の遷移を可能にするために、1度に1つ以上の「レベル」をロードするための十分なメモリを必要としますのでご注意ください。

...
// Initialize the sound engine here.
...
// Load Init bank and Common bank.
AkBankID bankID; // Not used in this sample.
AKRESULT eResult = AK::SoundEngine::LoadBank( L"Init.bnk", AK_DEFAULT_POOL_ID, bankID );
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"CommonEvents.bnk", AK_DEFAULT_POOL_ID, bankID );
}
...
// And at various places in the code, based on the actual needs:
eResult = AK::SoundEngine::LoadBank( L"Level_1.bnk", AK_DEFAULT_POOL_ID, bankID );
...
eResult = AK::SoundEngine::LoadBank( L"Level_2.bnk", AK_DEFAULT_POOL_ID, bankID );
...
eResult = AK::SoundEngine::LoadBank( L"Level_3.bnk", AK_DEFAULT_POOL_ID, bankID );
...
eResult = AK::SoundEngine::UnloadBank( L"Level_1.bnk", NULL );
...
eResult = AK::SoundEngine::UnloadBank( L"Level_2.bnk", NULL );
...
eResult = AK::SoundEngine::UnloadBank( L"Level_3.bnk", NULL );

このメソッドに関する補足事項

長所:

  • “オールインワン” バンクのテクニックより必要とされるメモリがはるかに少ない。
  • ゲームへの統合が非常に簡単である。

短所:

  • オーディオ要件が、メインキャラクターの位置のような単純な事実のみでなく、その他のさまざまな条件によって駆動されるオンラインまたはイベントベースのゲームには適さない。
  • バンクは重複データを含めることができるため、メモリにロードされるオーディオソースの重複が起こる可能性がある。
  • 異なるバンクが同様のコンテンツを持つことができるため、ディスク上のバンク総容量が増える可能性がある。

メソッド3:メディアの微細管理

このメソッドは以下の場合に適用可能です:

  • ゲームが多数のメモリ内メディアアセットを持つ。
  • サウンドデザイナーによるメディア要求の事前予測が困難である。
  • 特定のイベントに対してどのサウンドを再生するかを決定するのにスイッチとステートを使用するプロジェクトである。
  • サウンドを定義したセクションへ簡単に分割することができない。

メソッドの実行方法:

ゲームは非常に複雑になる場合があり、サウンドのトリガーは、ゲームのテクスチャ、時間帯やゲームオブジェクトの動き、オンラインマルチプレイヤーゲームでは、他のプレイヤーのアクションなど、様々な要因に基づく可能性があります。例えば、イベントベースまたはオブジェクトベースの環境では、他のゲームオブジェクトの近接性に基づいてサウンドがメモリにロードされます。それぞれのゲームオブジェクトは、それが特定の範囲内に入ったり、単に存在するとロードされるバンクのリストを持つことができます。

また、スイッチとステートは、再生するサウンドを決定することができます。当該サウンドを再生するイベントがバンクへ追加されると、すべての再生可能性のあるメディアも自動的にバンクへ追加されます。例えば、"Play_Footstep" という単一のイベントがあるとします。このイベントは、現在の地面のテクスチャに基づいて適切なサウンドを再生しますが、これはスイッチを変更することにより指定することができます。これは、うまく機能するのですが、ゲームプレイがロンドンの建物内で起こっている場合に、砂地の足音サウンド "footstep_sand.wav" や冬場の足音サウンド "footstep_winter.wav" をメモリ内に待機させておくのはメモリの浪費になり得ます。

この場合のメモリ浪費を回避するには、イベントと/またはサウンド構造をバンクに追加し、バンクに含められるべき対応サウンドを指定します。例えば、異なるテクスチャ上の足音サウンドを使用する場合、次のようなバンクを作成することができます:

  • "Play_Footstep" イベントと構造体を含む "EventBank"。
  • ゲームの一部(冬)でのみ発生する足音用のメディアを含む "Winter_Footstep_bank"。
  • ゲームの一部(砂漠)でのみ発生する足音用のメディアを含む "Desert_Footstep_bank"。
  • ゲーム内のあらゆる場所(木の床、コンクリート面など)で発生する足音用のメディアを含む "Common_Footstep_bank"。

Wwise 側

先の例を再作成します:

3つの異なるテクスチャがあるとします(雪、砂、コンクリート)。Wwise では、"ground_texture" スイッチに基づいて、3つのランダムコンテナの1つを再生するスイッチコンテナがあります。3つのランダムコンテナのそれぞれには、特定のテクスチャ用の足音サウンドのバリエーションが4つ入っています。

  1. "EventBank" という名前のバンクを作成し、これを SoundBank Editor にロードする。
  2. "Play_Footstep" イベントを、SoundBank Editor の Add タブにドラッグする。
  3. このイベント用の "Media" チェックボックスの選択を解除し、"Events" と "Structures" チェックボックスは選択したままにする。
  4. 各テクスチャ用に1つずつ、3つのバンクを作成する。
  5. 各バンクに、そのテクスチャと関連付けられたランダムコンテナをドラッグする。
    注釈: ランダムコンテナをドラッグ&ドロップする代わりに、サウンドを個別にドラッグ&ドロップすることもできます。 しかし、コンテナの使用の利点は、コンテナ内のコンテンツに変更があった場合に手動で変更を加えなければならない代わりに、コンテナ内のすべてのサウンドを自動的にバンクへ追加できることです。
  6. 3つのテクスチャバンクそれぞれの "Events" と "Structures" チェックボックスの選択を解除する、"Media" チェックボックスだけ選択したままにしておく。
  7. バンクを生成し、生成されたバンクフォルダをゲームアプリケーションに追加する。

これで、4つのバンクができました。再生されるオーディオに関連するイベントと構造データを含むバンクと、特定の地面テクスチャに関連付けられたメディアのみを含む3つのバンクです。

ゲーム側

// Load Init and the EventBank
AkBankID bankID; // Not used in this sample.
AKRESULT eResult = AK::SoundEngine::LoadBank( L"Init.bnk", AK_DEFAULT_POOL_ID, bankID );
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"EventBank.bnk", AK_DEFAULT_POOL_ID, bankID );
}
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"Common_Footstep_bank.bnk", AK_DEFAULT_POOL_ID, bankID );
}
...
// And at various places in the code, possibly based on the location:
eResult = AK::SoundEngine::LoadBank( L"Winter_Footstep_bank.bnk", AK_DEFAULT_POOL_ID, bankID );
...
eResult = AK::SoundEngine::LoadBank( L"Desert_Footstep_bank.bnk", AK_DEFAULT_POOL_ID, bankID );
...
eResult = AK::SoundEngine::UnloadBank( L"Winter_Footstep_bank.bnk", NULL );
...
eResult = AK::SoundEngine::UnloadBank( L"Desert_Footstep_bank.bnk", NULL );

このメソッドに関する補足事項

この手法を用いて実行可能な事は多数あり、上記はそのうちの1つの非常に具体的な例にすぎません。各バンクに含めるサウンドやイベントを1つ1つ決めることができるので、各バンクのコンテンツを完全に制御することができます。ゲーム内の各サウンドに対して個別のバンクを作成できますが、すべての新規サウンドは、ゲーム内の適切な場所でバンクをロードするための新しいコードを必要とするため、これを維持するのは非常に困難になります。各ゲームのゴールは、粒度と統合の容易さの間の良いバランスを見つけることです。

Tip: サウンドを1つずつ個別にロードする方法に関心がある場合は、LoadBank の代わりに PrepareEvents の使用を検討してみてください。

長所:

  • メモリ使用量を最適化するための最良のオプション。
  • ゲームの任意の時点でどのメディアをロードするか完全制御できる。

短所:

  • どのバンクをどの時点でロードするかを決定するために、サウンドデザイナーとゲーム開発者間で多くのコミュニケーションを必要とする。

メソッド4:Event(イベント)を準備

このメソッドは以下の場合に適用可能です:

  • メディアのメモリ使用量を低く保つために、非常に細かい粒度レベルが必要である。
  • メディアアセットを複数のバンクに分割する手間を避けたい。

準備済みイベントとは?PrepareEvent 関数を呼び出すと、システムはイベントを分析し、当該イベントに関連するすべての構造体とメディアがメモリにロードされていることを確認します。もしも、このロードが行われていない場合、システムは、欠落している情報をディスクから自動的にストリーミングします。イベントは、明示的に準備解除されるまで準備済みの状態になります。

メソッドの実行方法:

このメソッドでは、メタデータ(構造やEvent)を含むSoundBankから、確実に、メディアを除外しておく必要があります。1つはメディア用、もう1つはイベント用です。構造部分は、これら2つのバンクまたは完全に別のサウンドバンクの一部のいずれかにすることができます。

PrepareEvent メカニズムを使用するSoundBankを構築する場合、唯一の基準は、すべての必要なEvent/構造体/メディアが少なくとも1つのSoundBankに入っていなければならないということです。ただし、構造体を複数のバンクに分割することで、より効率的にメモリの管理ができるということを覚えておいてください。

Eventの準備に先立って、(LoadBank() を使用して)Event自体をSoundBankからメモリへロードしておかなくてはなりません。Eventには、Eventの準備に必要な依存関係についての情報が含まれているためです。

Wwise 側

  1. "Events" という名前のサウンドバンクを作成し、これを SoundBank Editor にロードします。
  2. プロジェクト内のEventをいくつか "Event" サウンドバンクに追加、または、単純にEvent Work Unitをそのまま追加します。
  3. "Media" および "Structures" チェックボックスの選択を解除し、"Events" チェックボックスのみを選択します。
  4. SoundBankを生成する。ルースメディアの1つまたは複数を参照しているSoundBank を生成すると、警告メッセージを受け取ります: SoundBank <bank>の <structure> が参照するメディアは、どのSoundBankにもありません。このメッセージで右クリックして、無視リスト追加することもできます。
  5. サウンドバンクが参照するルースメディアは、デフォルトでは、CopyStreamedFiles ツールを使ってSoundBankと同じ出力ディレクトリにコピーされます。
  6. バンクを生成し、生成されたバンクフォルダをゲームアプリケーションにコピーします。
注釈: 単一バンク内に含まれる構造体データは、ランタイム時には分割できません。したがって、AK::AoundEngine::PrepareEvent 使用時に、別のバンクからの構造体データが要求された場合、そのバンク内のすべての構造体が一度にロードされます。このため、プロジェクト内の構造体の内容を複数のバンクに分割して、メモリにロードされた不要な情報の量を最小限に抑えることができます。

ゲーム側

// Initializing the sound engine.
AkInitSettings initSettings;
AkPlatformInitSettings platformInitSettings;
// Set the required settings
...
// Set PrepareEvent related settings
initSettings.bEnableGameSyncPreparation = false; // Not used in the current sample.
// Allocate a memory pool into which prepared media will be loaded.
// If this is not done, prepare operations will fail.
{
// (Optional) Give the memory pool a name. This can be very useful for profiling.
AK::MemoryMgr::SetPoolName( initSettings.uPrepareEventMemoryPoolID, L"PrepareEventPool" );
}
AKRESULT eResult = AK.SoundEngine.Init( initSettings, platformInitSettings );
if( eResult != AK_Success )
{
// Handle error.
}
// Load Init bank and the event/structure bank.
AkBankID bankID; // Not used in this sample.
AKRESULT eResult = AK::SoundEngine::LoadBank( L"Init.bnk", AK_DEFAULT_POOL_ID, bankID );
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"Events.bnk", AK_DEFAULT_POOL_ID, bankID );
}
...
// And then, at various points in the code:
const char * pEventsNameArray[1] = { "My_Event_Name" };
// Preparing an event:
eResult = AK::SoundEngine::PrepareEvent( Preparation_Load, pEventsNameArray, 1 ); // 1 is the array size
// Unpreparing an event:
eResult = AK::SoundEngine::PrepareEvent( Preparation_Unload, pEventsNameArray, 1 ); // 1 is the array size

このメソッドに関する補足事項

AK::SoundEngine::PrepareEvent への呼び出し(コール)は、I/O 関数呼び出しであると考える必要があることに留意してください。先の例では、ブロック関数を使用しました。AK::SoundEngine::PrepareEvent 関数の他のオーバーロードを使用して、これらを非ブロック関数にし、別のコールバックを使用して完了通知を復活させることができます。

長所:

  • バンク生成プロセスが単純である。
  • メディアのための粒度レベルが非常に細かい。
  • 全体的なメモリ使用量を低く維持できる。
  • プロセスの自動化が簡単である。

短所:

  • メディアアセットが1つ1つロードされるごとに、ディスクのリードおよびシークの回数が潜在的に増加する。
  • 使用されるメモリの総量を制御しにくい。
  • インタラクティブミュージックには適さない。

メソッド5:Eventとゲームシンク(SwitchとState)を準備

このメソッドは以下の場合に適用可能です:

  • メディアのメモリ使用量を低く保つために、細かい粒度レベルが必要である。
  • メディアアセットを複数のバンクに分割する手間を省きたい。
  • スイッチやステートに基づいてさまざまなサウンドを再生するイベントがプロジェクトに含まれている。
  • スイッチやステートに基づいてミュージックを再生するインタラクティブミュージックがプロジェクトに含まれている。

このメソッドは基本的には先のメソッド(sdk_bank_training_Method_4)と同じですが、イベントが準備される時にロードされるメディアをより細かく制御することができます。このメソッドでは、準備済みイベントと現在アクティブになっているゲームシンクの両方に関連付けられたメディアのみがメモリにロードされます。

次の2つのイベントを持つ単純なプロジェクトがあるとします:"Play_Maincharacter_FootSteps" と "Play_Monster_Footsteps"。それぞれのイベントは、移動するキャラクター下の地面のテクスチャに基づいて異なるランダムサウンドを再生するスイッチコンテナを再生させます。スイッチグループ名は "GroundTexture" で、以下の3つのステートを含んでいます:"Snow"、"Concrete"および"Sand"。

Wwise 内のスイッチコンテナ階層は、以下のようになります:

Switch_Container_Footstep_Main_Character

  • Random_Container_Sound_Snow_main
    • Sound_Snow_main_1
    • Sound_Snow_main_2
    • Sound_Snow_main_3
  • Random_Container_Sound_Concrete_main
    • Sound_Concrete_main_1
    • Sound_Concrete_main_2
    • Sound_Concrete_main_3
  • Random_Container_Sound_Sand_main
    • Sound_Sand_main_1
    • Sound_Sand_main_2
    • Sound_Sand_main_3

および

Switch_Container_Footstep_Monster

  • Random_Container_Sound_Snow_Monster
    • Sound_Snow_Monster_1
    • Sound_Snow_Monster_2
    • Sound_Snow_Monster_3
  • Random_Container_Sound_Concrete_Monster
    • Sound_Concrete_Monster_1
    • Sound_Concrete_Monster_2
    • Sound_Concrete_Monster_3
  • Random_Container_Sound_Sand_main
    • Sound_Sand_Monster_1
    • Sound_Sand_Monster_2
    • Sound_Sand_Monster_3

この例では、メモリにロードされる可能性のあるサウンドが18(3 サウンドより成る6つのグループ)あります。

メソッド4:Event(イベント)を準備 メソッドを使用することもできますが、イベントごとにメモリへロードされる6サウンドより細かい粒度レベルを得ることはできません。より細かい粒度レベルを得るために、 メソッド3:メディアの微細管理 メソッドを使用することも可能ですが、この単純なプロジェクトのために6つの異なるバンクを作成する必要があります(実際のプロジェクトでは、バンク数は急激に増加します)。そして、モンスター出現時には、どのようなテクスチャが可能であるか確認し、適切なバンクをロードする必要があります。

当メソッドでは、どのイベントとゲームシンクを使用する可能性があるかを指定するだけで、適切なメディアのみがロードされます。更に簡素化するために、全てのメディアを単一のバンクにグループ化することもできます。

メソッドの実行方法:

Wwise 側

  1. "Events" という名前のバンクを1つ作成し、これを SoundBank Editor にロードします。
  2. 2つのイベントを SoundBank Editor の Add タブにドラッグします。
  3. 両方のイベントに対して、"Media" および "Structures" チェックボックスの選択を解除し、"Events" チェックボックスのみを選択します。
  4. バンクを生成し。ルースメディアの1つまたは複数を参照しているSoundBank を生成すると、警告メッセージを受け取ります: SoundBank <bank>の <structure> が参照するメディアは、どのSoundBankにもありません。このメッセージで右クリックして、無視リスト追加することもできます。
  5. バンクが参照するルースメディアは、デフォルトでは、CopyStreamedFiles ツールを使ってSoundBankと同じ出力ディレクトリにコピーされます。
  6. バンクを生成し、生成されたバンクフォルダをゲームアプリケーションにコピーします。

ゲーム側

  • 2つのイベントがゲームによって要求される前に "Event" バンクをロードする。
  • 可能な地面テクスチャが近くにある場合は、ゲームシンクを有効にする。
  • Concrete (コンクリート面)テクスチャを常時有効にする。
  • メインキャラクターの足音イベントを常時準備しておく。
注釈: 単一バンク内に含まれる構造体データは、ランタイム時には分割できません。したがって、AK::AoundEngine::PrepareEvent 使用時に、別のバンクからの構造体データが要求された場合、そのバンク内のすべての構造体が一度にロードされます。このため、プロジェクト内の構造体の内容を複数のバンクに分割して、メモリにロードされた不要な情報の量を最小限に抑えることができます。
// Initializing the sound engine.
AkInitSettings initSettings;
AkPlatformInitSettings platformInitSettings;
// Set the required settings.
...
// Set PrepareEvent related settings.
////////////////////////////////////////////////////////////////
// The flag bEnableGameSyncPreparation is set to true to activate
// the prepare gamesync mechanism. When set to false, the media
// associated with all game syncs is loaded and there is no need
// to call AK::SoundEngine:PrepareGameSyncs.
//
// When set to true, no media that is game sync dependent will be
// loaded unless the game sync is activated by calling AK::SoundEngine:PrepareGameSyncs
////////////////////////////////////////////////////////////////
initSettings.bEnableGameSyncPreparation = true;
// Allocate a memory pool into which prepared media will be loaded.
// If this is not done, prepare operations will fail.
{
// (Optional) Give the memory pool a name. This can be very useful for profiling.
AK::MemoryMgr::SetPoolName( initSettings.uPrepareEventMemoryPoolID, L"PrepareEventPool" );
}
AKRESULT eResult = AK.SoundEngine.Init( initSettings, platformInitSettings );
if( eResult != AK_Success )
{
// Handle error.
}
// Load Init and the event/structure bank.
AkBankID bankID; // Not used in this sample.
AKRESULT eResult = AK::SoundEngine::LoadBank( L"Init.bnk", AK_DEFAULT_POOL_ID, bankID );
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"Events.bnk", AK_DEFAULT_POOL_ID, bankID );
}
// ... At this point,
// the two events are loaded, but not prepared. No media is currently loaded.
const char * pNameArray[1];
// Prepare the main character footstep event.
pNameArray[0] = "Play_Maincharacter_FootSteps";
eResult = AK::SoundEngine::PrepareEvent( Preparation_Load, pNameArray, 1 ); // 1 is the array size
// ... At this point,
// one event has been prepared, but no media has been loaded yet.
// Now since concrete is always available in the game.
pNameArray[0] = "Concrete";
eResult = AK::SoundEngine::PrepareGameSyncs( Preparation_Load, in_eType, "GroundTexture", pNameArray, 1 );
// ... At this point,
// the 3 sounds, Sound_Concrete_main_1, Sound_Concrete_main_2, and Sound_Concrete_main_3 are loaded.
// Now, let's say that the main character enters a land where there is snow.
pNameArray[0] = "Snow";
eResult = AK::SoundEngine::PrepareGameSyncs( Preparation_Load, in_eType, "GroundTexture", pNameArray, 1 );
// ... At this point,
// 3 more sounds just got loaded : Sound_Snow_main_1, Sound_Snow_main_2 and Sound_Snow_main_3
// Then let's say that a Monster suddenly appears.
pNameArray[0] = "Play_Monster_Footsteps";
eResult = AK::SoundEngine::PrepareEvent( Preparation_Load, pEventsNameArray, 1 ); // 1 is the array size
// ... At this point,
// 6 more sounds just got loaded ( Sound_Concrete_Monster_1.2.3 and Sound_Snow_Monster_1.2.3 )
// And now our player decides to run away from the monster, and the monster goes after him.
// They run so far that they arrive at a place where there is no snow anymore.
pNameArray[0] = "Snow";
eResult = AK::SoundEngine::PrepareGameSyncs( Preparation_Unload, in_eType, "GroundTexture", pNameArray, 1 );
// ... At this point,
// The 6 sounds that were related to snow ( Sound_Snow_Monster_1.2.3 and Sound_Snow_main_1.2.3 ) are unloaded from memory.
...
注釈: AK::SoundEngine::PrpareEvent と AK::SoundEngine::PrepareGameSync を呼び出す順序は重要ではありません。ステートが変化するたびに、イベントとゲームシンクのクロスマッチによりメディアプールが更新されます。

このメソッドに関する補足事項

長所:

  • バンク生成プロセスが単純である。
  • メディアのための粒度レベルが非常に細かい。
  • 全体的なメモリ使用量を低く維持できる。
  • プロセスの自動化が簡単である。
  • 有用なメディアのみがロードされる。

短所:

  • メディアアセットが1つ1つロードされるごとに、ディスクのリードおよびシークの回数が潜在的に増加する。
  • 使用されるメモリの総量を制御しにくい。
  • ゲームシンクを有効化すると、新しいデータのロードを必要とするイベントが多数準備される際に、ストリーミング帯域幅が高くなる可能性がある。
参照
AKSOUNDENGINE_API AKRESULT PrepareEvent(PreparationType in_PreparationType, const char **in_ppszString, AkUInt32 in_uNumEvent)
Audiokinetic namespace
AKSOUNDENGINE_API AKRESULT PrepareGameSyncs(PreparationType in_PreparationType, AkGroupType in_eGameSyncType, const char *in_pszGroupName, const char **in_ppszGameSyncName, AkUInt32 in_uNumGameSyncs)
AKSOUNDENGINE_API AKRESULT SetPoolName(AkMemPoolId in_poolId, const char *in_pszPoolName)
AKSOUNDENGINE_API void GetDefaultInitSettings(AkInitSettings &out_settings)
AkMemPoolId uPrepareEventMemoryPoolID
Memory pool where data allocated by AK::SoundEngine::PrepareEvent() and AK::SoundEngine::PrepareGameS...
Definition: AkSoundEngine.h:214
AKSOUNDENGINE_API AKRESULT UnloadBank(const char *in_pszString, const void *in_pInMemoryBankPtr, AkMemPoolId *out_pMemPoolId=NULL)
AKSOUNDENGINE_API void GetDefaultPlatformInitSettings(AkPlatformInitSettings &out_platformSettings)
AKSOUNDENGINE_API AKRESULT LoadBank(const char *in_pszString, AkMemPoolId in_memPoolId, AkBankID &out_bankID)

このページはお役に立ちましたか?

サポートは必要ですか?

ご質問や問題、ご不明点はございますか?お気軽にお問い合わせください。

サポートページをご確認ください

あなたのプロジェクトについて教えてください。ご不明な点はありませんか。

プロジェクトを登録していただくことで、ご利用開始のサポートをいたします。

Wwiseからはじめよう