版本

menu_open
Wwise SDK 2024.1.0
SoundBank 集成示例

以下各节包含各种 SoundBank 管理策略的集成示例。有关这些策略的详细信息,请参阅 Wwise Help 中的 SoundBank 管理策略

备注: PrepareEvent 和 LoadBank 不可共用,因为两者都会将数据加载到内存中。


"All-in-one" SoundBank

在采用此策略时,所有 Event 内容、声音结构数据和媒体文件会全部存储在一个 SoundBank 中。有关该策略的论述及其在 Wwise 设计工具中的实现,请参阅 Wwise Help 中的 "All-in-one" SoundBank

此游戏只有一个 SoundBank,在初始化游戏时加载它就行。当然,必须先初始化声音引擎。

...
// 在此初始化声音引擎。
...
// 加载 "Init" 和 "All-in-one" SoundBank。
AkBankID bankID; // 此示例中未使用。
AKRESULT eResult = AK::SoundEngine::LoadBank( L"Init.bnk", bankID );
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"MyAllInOneBank.bnk", bankID );
}
...

多个完整的 SoundBank

此策略比较适合单人游戏。其中所有可能用到的声音都是由玩家在游戏中的位置决定的。有关该策略的论述及其在 Wwise 设计工具中的实现,请参阅 Wwise Help 中的多个完整的 SoundBank

在游戏中,要适时加载正确的 SoundBank。例如,游戏可以在开始时加载通用 SoundBank ,然后根据游戏中玩家的实际位置加载其它 SoundBank 。注意,有些游戏需要有足够的内存才能一次加载多个关卡来实现关卡之间的过渡。

除了 LoadBank() ,还可使用 AkBankContent_All 来预备 SoundBank。这样可以避免在内存中重复加载媒体(参见 对 SoundBank 做 Prepare 操作 章节)。

...
// 在此初始化声音引擎。
...
// 加载初始化 Bank 和通用 SoundBank 。
AkBankID bankID; // 此示例中未使用。
AKRESULT eResult = AK::SoundEngine::LoadBank( L"Init.bnk", bankID );
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"CommonEvents.bnk", bankID );
}
...
// 在代码中多处,取决于实际需要:
eResult = AK::SoundEngine::LoadBank( L"Level_1.bnk", bankID );
...
eResult = AK::SoundEngine::LoadBank( L"Level_2.bnk", bankID );
...
eResult = AK::SoundEngine::LoadBank( L"Level_3.bnk", 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 );

细致地管理媒体

对于包含很多素材的复杂游戏,可考虑采用此策略。有关该策略的论述及其在 Wwise 设计工具中的实现,请参阅 Wwise Help 中的细致地管理媒体

在游戏开始时加载通用 SoundBank,然后在需要时加载其他 SoundBank。比如,游戏可在开始时加载 "Event" SoundBank 和通用脚步声 SoundBank,然后根据玩家在游戏中的位置加载其他 SoundBank。

// 加载初始化和事件 SoundBank
AkBankID bankID; // 此示例中未使用。
AKRESULT eResult = AK::SoundEngine::LoadBank( L"Init.bnk", bankID );
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"EventBank.bnk", bankID );
}
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"Common_Footstep_bank.bnk", bankID );
}
...
// 在代码中多处,可能取决于位置:
eResult = AK::SoundEngine::LoadBank( L"Winter_Footstep_bank.bnk", bankID );
...
eResult = AK::SoundEngine::LoadBank( L"Desert_Footstep_bank.bnk", bankID );
...
eResult = AK::SoundEngine::UnloadBank( L"Winter_Footstep_bank.bnk", NULL );
...
eResult = AK::SoundEngine::UnloadBank( L"Desert_Footstep_bank.bnk", NULL );

预备 Action Event

若需要较高的媒体粒度以便降低内存用量,但又不想管理与 Event 相关的结构和媒体,可考虑采用此策略。有关该策略的论述及其在 Wwise 设计工具中的实现,请参阅 Wwise Help 中的预备 Action Event

在游戏开始时加载 Event 所在的 SoundBank,然后在游戏中需要时预备 Event。系统会自动加载对应的结构和媒体。

// 初始化声音引擎。
AkInitSettings initSettings;
AkPlatformInitSettings platformInitSettings;
// 设置所需的设置。
...
// 设置 PrepareEvent 相关设置。
initSettings.bEnableGameSyncPreparation = false; // 当前示例中未使用。
AKRESULT eResult = AK::SoundEngine::Init( initSettings, platformInitSettings );
if( eResult != AK_Success )
{
// Handle error.
}
// 加载初始化 SoundBank 和事件/结构 SoundBank 。
AkBankID bankID; // 此示例中未使用。
AKRESULT eResult = AK::SoundEngine::LoadBank( L"Init.bnk", bankID );
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"Events.bnk", bankID );
}
...
// 然后在代码中的各个位置:
const char * pEventsNameArray[1] = { "My_Event_Name" };
// Prepare 事件:
eResult = AK::SoundEngine::PrepareEvent( Preparation_Load, pEventsNameArray, 1 ); // 1 is the array size
// 撤消 Prepare 事件:
eResult = AK::SoundEngine::PrepareEvent( Preparation_Unload, pEventsNameArray, 1 ); // 1 is the array size

预备 Event 和 Game Sync(Switch 和 State)

此策略跟 预备 Action Event 基本相同,不过在预备 Event 时可更好地控制所加载的媒体。有关该策略的论述及其在 Wwise 设计工具中的实现,请参阅 Wwise Help 中的预备 Event 和 Game Sync(Switch 和 State)

AK::SoundEngine::PrepareEventAK::SoundEngine::PrepareGameSync 的调用顺序并不重要。每次状态改变都会通过交叉匹配 Event 和 Game Sync 来更新媒体池。

// 初始化声音引擎。
AkInitSettings initSettings;
AkPlatformInitSettings platformInitSettings;
// 设置所需的设置。
...
// 设置 PrepareEvent 相关设置。
////////////////////////////////////////////////////////////////
// bEnableGameSyncPreparation 标志设为 true,以激活
// 准备游戏同步器机制。当设置为 false 时,与所有游戏
// 同步器相关的媒体将加载,并且无需
// 调用 AK::SoundEngine:PrepareGameSyncs。
//
// 当设置为 true 时,不会加载与游戏同步器相关的媒体,
// 除非游戏同步器已通过调用 AK::SoundEngine:PrepareGameSyncs 被激活
////////////////////////////////////////////////////////////////
initSettings.bEnableGameSyncPreparation = true;
AKRESULT eResult = AK.SoundEngine.Init( initSettings, platformInitSettings );
if( eResult != AK_Success )
{
// 处理错误。
}
// 加载初始化 Bank 和事件/结构 SoundBank 。
AkBankID bankID; // 此示例中未使用。
AKRESULT eResult = AK::SoundEngine::LoadBank( L"Init.bnk", bankID );
if( eResult == AK_Success )
{
eResult = AK::SoundEngine::LoadBank( L"Events.bnk", bankID );
}
// ... 在此时,
// 两个事件已加载但尚未 Prepare。当前没有加载媒体。
const char * pNameArray[1];
// Prepare 主人公脚步事件。
pNameArray[0] = "Play_Maincharacter_FootSteps";
eResult = AK::SoundEngine::PrepareEvent( Preparation_Load, pNameArray, 1 ); // 1 是数组大小
// ... 在此时,
// 已 Prepare 一个事件,但尚未加载任何媒体。
// 从现在起,游戏中始终可用 concrete。
pNameArray[0] = "Concrete";
eResult = AK::SoundEngine::PrepareGameSyncs( Preparation_Load, in_eType, "GroundTexture", pNameArray, 1 );
// ... 在此时,
// 已加载 3 个声音:Sound_Concrete_main_1、Sound_Concrete_main_2 和 Sound_Concrete_main_3。
// 现在,假设主人公进入一片雪地。
pNameArray[0] = "Snow";
eResult = AK::SoundEngine::PrepareGameSyncs( Preparation_Load, in_eType, "GroundTexture", pNameArray, 1 );
// ... 在此时,
// 又加载了 3 个声音:Sound_Snow_main_1、Sound_Snow_main_2 和 Sound_Snow_main_3
// 然后假设怪兽突然在此时出现。
pNameArray[0] = "Play_Monster_Footsteps";
eResult = AK::SoundEngine::PrepareEvent( Preparation_Load, pEventsNameArray, 1 ); // 1 是数组大小
// ... 在此时,
// 又加载了 6 个声音( Sound_Concrete_Monster_1.2.3 和 Sound_Snow_Monster_1.2.3)
// 现在我们的玩家决定逃离怪兽,而怪兽在玩家身后紧追不舍。
// 怪兽和玩家一直奔跑,来到没有积雪的地方。
pNameArray[0] = "Snow";
eResult = AK::SoundEngine::PrepareGameSyncs( Preparation_Unload, in_eType, "GroundTexture", pNameArray, 1 );
// ... 在此时,
// 与积雪相关的 6 个声音(Sound_Snow_Monster_1.2.3 和 Sound_Snow_main_1.2.3)已从内存中卸载。
...
参见
AKSOUNDENGINE_API AKRESULT PrepareEvent(PreparationType in_PreparationType, const char **in_ppszString, AkUInt32 in_uNumEvent)
Definition of data structures for AkAudioObject
AKSOUNDENGINE_API AKRESULT PrepareGameSyncs(PreparationType in_PreparationType, AkGroupType in_eGameSyncType, const char *in_pszGroupName, const char **in_ppszGameSyncName, AkUInt32 in_uNumGameSyncs)
AKSOUNDENGINE_API AKRESULT Init(AkInitSettings *in_pSettings, AkPlatformInitSettings *in_pPlatformSettings)
AkUInt32 AkBankID
Run time bank ID
Definition: AkTypes.h:75
AKRESULT
Standard function call result.
Definition: AkTypes.h:134
AKSOUNDENGINE_API AKRESULT LoadBank(const char *in_pszString, AkBankID &out_bankID, AkBankType in_bankType=AkBankType_User)
@ Preparation_Unload
PrepareEvent() will unload required information to play the specified event.
#define NULL
Definition: AkTypes.h:46
@ AK_Success
The operation was successful.
Definition: AkTypes.h:136
AKSOUNDENGINE_API void GetDefaultInitSettings(AkInitSettings &out_settings)
@ Preparation_Load
PrepareEvent() will load required information to play the specified event.
AKSOUNDENGINE_API AKRESULT UnloadBank(const char *in_pszString, const void *in_pInMemoryBankPtr, AkBankType in_bankType=AkBankType_User)
AKSOUNDENGINE_API void GetDefaultPlatformInitSettings(AkPlatformInitSettings &out_platformSettings)

此页面对您是否有帮助?

需要技术支持?

仍有疑问?或者问题?需要更多信息?欢迎联系我们,我们可以提供帮助!

查看我们的“技术支持”页面

介绍一下自己的项目。我们会竭力为您提供帮助。

来注册自己的项目,我们帮您快速入门,不带任何附加条件!

开始 Wwise 之旅