Wwise
思维上的转变:发送给声音引擎的Event是游戏逻辑,比如游戏世界中发生了什么;而不是播放某一个声音的命令,具体哪个声音播放、停止、声音效果等都由声音引擎控制,职责不要越界
对话流程中,一般是由Wwise控制打断、停止,发事件即可
官方宣讲资料Wwise-programming.pdf:Dropbox (Public/Wiki/Wwise)
介绍
跨平台
多语言
互动音乐
对话控制
Bank内容
There is only one Initialization bank for each project. It is automatically created when Wwise generates the SoundBanks and is named “Init.bnk”. This special bank contains general project information, including:
Bus hierarchy
States
Switches
RTPCs
Bus Effects
Each SoundBank may contain:
Event definitions
Sound structure information (sound, container, music object, Actor-Mixer, and so on)
Media:
Sound data (for in-memory sounds)
Prefetched sound data (for zero-latency streamed sounds)
References to streamed audio files (file ID)
路径管理
BasePath / AddPath / AddBasePath
默认的内容分发
打包时,音频资源会被放置到StreamingAssets中,打包结束后,对应资源会被清理
运行时,直接从StreamingAssets中读取数据
数据更新时,将新的音频内容作为DLC进行分发,通过AddPath等接口,找到新的资源并读取
Addressable的内容分发
音频资源和其他类型的资源一样,走Addressable的接口进行分发、更新
Action
Wwise编辑器中,Event由Action组成,类型如下
在程序端,也可以在Event上触发一些Action,比如Pause、Resume等。类型参考:AkActionOnEventType
[存疑]上面提到的两种Action严格来说并不是同一种,可选的Action种类也不同
空间音频
每一个发声物体在使用之前都需要注册(注册为AkGameObj)
发声物体的位置由引擎控制,使用类似SetPosition的接口,所以如果需要的话,发声位置(AkGameObj的位置)可以和游戏内逻辑上的游戏对象(比如Unity中的GameObject)位置不同,类似:SetPosition(x.wwise_id, x.logic_pos + offset)。除了位置,朝向也是同理
自行集成SDK
编译的时候可能需要AK_OPTIMIZED(宏):比如Link的是Release的Lib,其中没有xxxd的符号,那么就需要定义AK_OPTIMIZED,这样代码就不会引用xxxd的函数,而是引用Release版本的xxx函数
零散
[来自文档]事件一旦集成到游戏中,Wwise 用户就可以继续打磨这些事件,更换或修改事件包含的动作或者它们引用的对象。由于游戏触发的仍是同一事件,因此不再需要程序员动手介入,也无需重新编译代码,Wwise 用户所做的更改就会在游戏中生效。
[来自文档]Switch 用于游戏对象上的状态切换,比如根据角色踩到的路面类型变化来切换脚步声;State 用于全局状态切换,比如根据游戏场景和进程发展来播放不同的音乐;RTPC 用于连续数值变化,比如利用车辆发动机转速的连续变化来影响发动机声音。
[来自文档]按照本文档中的方式集成了 SoundBank 之后,要注意 AK::SoundEngine::LoadBank()
API 将所有数据一次性载入内存;如果需要采用流播放以节省内存,则程序员一般无须干预,由设计师在设计工具中指定。采用流播放后 Wwise 会在 SoundBank 的存放位置生成扩展名为.wem的文件,这些文件包含播放用的确切音频数据,需要和 SoundBank 文件一同部署到目标平台,但程序只需加载.bnk文件,不需要管理.wem文件。
[存疑]Init Bank中包含了所有的Game Syncs,包括States、Switches和RTPCs等,只要加载了Init Bank,所有的Game Syncs就都可以使用了,不再需要额外处理资源的加载(这一点和Event不同:触发Event之前需要确保其所在的Bank被加载了)
程序和音频之间,使用Event Name(字符串)作为协作标准没有什么问题(虽然字符串比ID慢一些,但是更方便易读)。但是,配置音频资源的时候,直接填写Event Name而没有检验机制是很危险的,所以应该提供解析Wwise输出文件,并提供选项的工具(一个Wwise Event Picker)
音效就像特效,是表现的最后一层。一般情况下都是,程序逻辑完全控制音效,音效逻辑不应该反过来影响游戏逻辑(单向控制)
问题和想法
Wwise中的Work Unit的具体用处是什么?和文件夹一样用于组织内容吗?为什么在文件夹之外还要做Work Unit这一层的管理,Work Unit和文件夹的不同之处在于什么?
注销一个Object的时候,在这个Object上触发的Event会自动停止吗?
Decode是在什么时候进行的,加载完成之后/播放之前/其他时候?Decode的时机可以控制吗?流式播放的媒体资源Decode的时机和方式和普通资源有不同之处吗?
关于Load Bank,显式加载和隐式加载的区别是什么?在流程控制上有何不同?(文档中关于隐式加载:In order to do this, you must first explicitly load a SoundBank that contains the definition of the Events and/or Game Syncs, through LoadBank(). Typically, these SoundBanks will contain only Events and structures, but no media, and thus be very lightweight. Refer to the Wwise Help to know how you can define a SoundBank that has no media data. 也就是说,即使是隐式加载,也必须显式调用LoadBank函数,只是真正的资源是延迟加载到内存中。而将Media文件放到Bank之外,是在Wwise中进行控制的,并不是程序可以干预的)
引擎集成 / 使用
文档
外链资料
常见问题