Motion 功能方便用户控制控制接口的触觉反馈。通过 Wwise,您可以使用您用于管理应用音频的相同功能集来管理 Motion(振动)。从内部来说,振动数据与音频数据并无差别。也就是说,所有适用于音频的功能同样适用于振动。Wwise 振动功能能够实现两种类型的触觉反馈。您可以在工程中使用音频信号并将其转换为振动,也可以使用 Motion Generator 源生成专用振动信号。只要配有支持的控制器,就可在 Windows 上直接使用 Wwise 设计工具来测试此功能。
Motion 利用 Wwise 声音引擎插件系统在应用程序中实现自身功能,并可划分为两个模块:音频源 (Motion Generator) 和音频设备 (Wwise Motion)。Motion Generator 是一款强大的可选工具,方便精确而灵活地设计振动。
Motion Sink 插件可被视为声音引擎和振动设备之间的连接纽带。正如其他 Sink 插件一样,它从一组听者接收数据,并负责将数据呈现给设备。此插件设在单独的库内,并需要同时包含在设计工具和应用程序中。请参阅 设置振动 一节了解更多信息。
利用 Motion Generator 源插件,您可以精确地设计触觉反馈效果器的行为。正如其他音频源一样,您可以将 Motion Generator 添加至 Wwise 工程中的 Sound SFX 节点,从而生成基于曲线的触觉反馈。请确保将 Sound SFX 节点的 Output Bus 设为振动总线。
为了在应用程序中使用振动功能,必须正确设置各个组件。注意,所有适用于音频流程的概念同样适用于振动。它使用相同的总线、听者和发声体(参阅“集成 Listener”)。
为了能向设备发送声音或振动数据,必须将经授权的 Wwise Motion ShareSet 添加至 Wwise 工程的 Audio Device 文件夹。Audio Device 文件夹位于 Project Explorer 的 ShareSets 选项卡中。Wwise Motion ShareSet 是声音引擎用来与振动设备进行交互的 Audio Device 插件。同时,必须将 Wwise Motion ShareSet 指派给顶层 Audio Bus。为简单起见,“振动总线”统称指派有 Wwise Motion ShareSet 的顶层 Audio Bus。为了方便排除故障和监控,最好在工程中使用单个振动总线层级结构。现在,您可以将任何 Sound SFX 的 Output Bus 设为振动总线,以便创建触觉反馈。通常,使用振动总线的 Sound SFX 元素会同时使用 Motion Generator 源。为了模拟音频和振动,Sound SFX 须至少拥有一条振动总线和一条音频总线(作为 Output Bus 或 Auxiliary Bus)。
在游戏端,首先须确保链接 AkMotionSink
库。此库为所支持平台的标准控制器提供支持。同时,还需包含 SDK\include\AK\plugin 下的 AkMotionSinkFactory.h 文件。此文件用于自动注册插件,因此必须包含在内。
|
Note: 在 Unity 中,会自动管理插件库。无需手动添加 AkMotionSink。 |
有关支持的控制器及其他要求,请参阅下表。
平台 | 设备 |
其他要求 |
Android |
支持振动效果的 Android 设备 |
|
iOS |
不支持。由于 Apple 的规格限制,iOS 设备上的触觉反馈 API 无法满足 Audiokinetic 对 Motion 功能的支持要求。 |
|
Linux |
不支持。 |
|
Mac |
不支持。 |
|
PlayStation 4 |
DUALSHOCK 4 |
|
Switch |
Joy-Con |
|
Windows | Xbox One 控制器 Xbox 360 控制器 DirectInput 控制器 |
XInput.lib |
Xbox One |
Xbox One 控制器 |
|
Note: 对于 Nintendo Switch,仅在 Joy-Con 处于单控制器模式时支持振动效果。 对于应用程序要结合振动使用的每个设备,都要添加专用输出。比如,对于连有四个玩家的分屏游戏,需要添加四个不同的输出以便各个控制器分别接收触觉反馈。若要添加输出设备,请使用 Wwise API 函数
注意,游戏控制器可能因连接问题或通信问题而断开。除了浪费一些资源外,它不会对声音引擎产生任何不利影响。若认为设备已经断开很长一段时间,则须调用 |
振动输出跟其他 Secondary Output 是一样的,因此也存在相同的限制和要求。假如您在制作单人游戏(即只有一个玩家在本地控制游戏),Listener/Game Object 设置会非常简单。一般情况下,新的振动输出将把同一默认 Listener 复用为主音频输出。也就是说,在单人设置中基本上不需要管理 Listener。
假如您在制作多人游戏,则需要为每个振动输出创建一个 Listener/Game Object。只有如此,各个玩家才能分别获得游戏情境产生的对应触觉反馈。在 AK::SoundEngine::AddOutput()
初始化输出的同时,必须初始化与设备关联的 Listener。各个 Listener 会为声音或振动提供附加通路层。在针对只与某个玩家的 Listener 关联的 Game Object 上播放 Event 时,可让声音只被该玩家听到。这一关联可通过调用 AK::SoundEngine::SetListeners
来完成。请参阅 集成 Listener 了解有关Listeners和Game Objects的更多信息。注意,您也可以将多个 Listener 与同一 Game Object 关联,生成作用于所有 Listener 的“广播”效果。
|
Note: 即便 Emitter 作为 Listener 采用振动输出,也要将对应的声音连入振动总线层级结构。 |
以下示例将展示如何设置应用程序以便使用振动效果。您也可以参阅 SDK 示例中 Integration Demo (DemoMotion.cpp) 的 Demo Motion。其中提供有所有支持平台的工作示例。
首先,像其他插件一样管理常规插件。您需要包含对应文件,并链接库(仅针对 Wwise 原生开发,在 Unity 上可忽略)。
#include "AkMotionSinkFactory.h" // 链接至 AkMotionSink.lib,并将输出实现输出到游戏控制器。 #include "AkMotionGeneratorSourceFactory.h" // 链接至 AkMotionGenerator.lib,并实现 Motion Generator 源。
然后,使用 Wwise 工程中设置的 Motion ShareSet 名称添加附加输出(在本例中名称为 Wwise_Motion)。因为要使用第一个相连的游戏控制器,所以在此将 0 用作输出 ID。
AkOutputSettings outputSettings("Wwise_Motion", 0); AK::SoundEngine::AddOutput(outputSettings);
然后,正常播放 Event。在 Wwise 工程中,Play_Explosion 事件指向的 Sound SFX 会输出至将 Wwise_Motion 共享集指派为 Audio Device 的总线。
AkGameObjectID explosionGO = 100; AK::SoundEngine::RegisterGameObj(explosionGO, "Explosion"); AK::SoundEngine::PostEvent("Play_Explosion", explosionGO);
确切地说,多人是指同一主机上的多个玩家,而非网络游戏中的多个玩家。在多人设置中,必须分别设置振动效果或玩家专用输出,以便反映玩家在游戏世界中的视角。为此,每个玩家都需要分别设置 Listener。
int NUM_PLAYERS = 4; const AkGameObjectID OBJ_FOR_PLAYER[MAX_PLAYERS] = {100 ,200, 300, 400}; // Game Object ID 可以任选。 for(int i = 0; i < NUM_PLAYERS; i++) { AK::SoundEngine::RegisterGameObj(OBJ_FOR_PLAYER[i]); // 注册要用作 Listener 的 GameObject。 AK::SoundEngine::SetListeners(OBJ_FOR_PLAYER[i], &OBJ_FOR_PLAYER[i], 1); // 让 Game Object 接收自己发出的声音。 }
然后,为每个玩家添加一个输出。每个 ShareSet 都可多次使用,无需设置多个 ShareSet。不过,需要为每个控制器设置一个实际设备 ID。本例适用于 Windows 上的 Xbox 控制器。有关如何针对特定平台检索设备 ID 的信息,请参阅“游戏设置”中的表格。
const AkUInt32 DEVICE_SPECIFIC_ID[MAX_PLAYERS] = {0, 1, 2, 3}; // 对于 Windows 上的 Xbox 控制器,设备 ID 为 0 ~ 3。其他平台有不同的要求。 for(i = 0; i < NUM_PLAYERS; i++) { AkOutputSettings settings("Wwise_Motion", DEVICE_SPECIFIC_ID[i]); // 使用 Wwise_Motion 共享集来驱动设备 DEVICE_SPECIFIC_ID[i]。 res = AK::SoundEngine::AddOutput(settings, &motionOutputIDs[i], &OBJ_FOR_PLAYER[i], 1); // 添加输出,并链接相应的 Listener。 }
然后,正常播放 Event。在 Wwise 工程中,Play_GunFire 事件指向的 Sound SFX 会输出至将 Audio Device 指派为 Wwise_Motion 共享集的总线。
AK::SoundEngine::PostEvent("Play_GunFire", OBJ_FOR_PLAYER[0]); // 鉴于 Game Object 和 Listener 的关系,将仅播放玩家控制的 0 号控制器。
若要播放的 Event 会影响多个设备,则需设置新的 Game Object,并将其作用于所有玩家专用 Listener。
AK::SoundEngine::RegisterGameObj(explosionGO, "Explosion"); // 注册要播放爆炸声的 Game Object。 AK::SoundEngine::SetListeners(explosionGO, OBJ_FOR_PLAYER, 4); // 将玩家控制的 4 个 Listener 全部绑定至该 Game Object,以便都能接收 Motion Effect。 AK::SoundEngine::PostEvent("Play_Explosion",explosionGO ); // 因为 4 个 Listener 全部都绑定至 explosionGO,所以 Play_Explosion 事件将广播给所有 Listener。
此外,还可参阅示例 IntegrationDemo 中的 DemoMotion
类。其中提供有多人设置示例。
为了确保特定设备可使用某个设备接收振动效果,必须执行以下操作:
AkMotionSink
库,同时链接 AkMotionSink 库。AK::SoundEngine::RegisterGameObj
创建要调用和接收振动事件的 Game Object。Ak::SoundEngine::AddOutput。若为多人设置,请分别提供
Listener 对象。在 Wwise 工程中设置 Motion:
为了排除故障,建议先对应用程序进行性能分析。在设计工具中您可以对应用程序做性能分析,方法是连接到应用程序并使用 Profiler 布局 (F6)。 您可以利用各项工具来了解问题的根源。在 Capture Log 视图中,可查看错误代码(显示为红色)。在 Graph 视图中,可查看声音引擎管线的图示。管线末端应会显示振动设备。若不显示,则表示声音引擎无法找到指定的设备。另外,还设有 Emitter/Listener 选项卡视图。在该视图中,将显示所有 Emitter-Listener 组合。若 Motion Effect 出现问题,则表示 Emitter 可能没有关联针对振动设备指定的 Listener。
若触发 Motion Effect 时出现问题,请执行以下操作:
AddOutput
时将在 Capture Log 中显示相应错误。RegisterGameObj、SetListeners
和
AddOutput
调用。对于 Android 设备,请务必在应用程序的 AndroidManifest.xml 文件中添加权限:
<uses-permission android:name="android.permission.VIBRATE"/>