查看原文
其他

史上最清晰的 Wwise 接入与使用分享丨Cocos Creator

乐府堂主 COCOS 2022-06-10

有小伙伴反应:在使用 Cocos Cretaor 开发原生游戏时,音频的表现常常不尽如人意。其实,我们可以通过使用一些专业的音效库,如 Wwise、fmod 等,提升原生游戏的音频表现。


乐府互娱的技术团队将通过今天的这篇文章,同大家分享在 Cocos Creator 中接入和使用 Wwise 的超详细技术实现过程,让你的原生游戏也能「纵享丝滑音质」。


Wwise 介绍


Wwise 是 Audiokinetic 公司出品的游戏互动音频解决方案,有一系列内置的空间音频功能。《刺客信条》、《守望先锋》、《崩坏3》、《王者荣耀》等一些我们耳熟能详的 3A 大作的音频模块都采用了 Wwise,很多游戏大厂,如腾讯、米哈游、游族、巨人、莉莉丝、畅游等都有专门的 Wwise 音效团队。


Wwise 提供包括多语言的实现、不同材质的脚步声、玩家的心跳声随着 HP 的变化而变化,以及 3D 音效、背景音效、配音强弱的控制等;其次还有游戏音效的性能优化和音效资源包体优化,包括 Wwise 的内置性能分析工具 Profiler 的使用,以及常见的音效性能瓶颈和针对性的优化策略等。


Wwise 使用准备


免费注册 Wwise 账号:

https://www.audiokinetic.com/zh/sign-up/


注册帐号并登陆后,注册一个项目后可以拿到授权,此步骤也可以最后再研究,不影响接入和测试使用。当前 Wwise 的免费版本一个项目最多支持500个音效,能够满足大部分中小项目需求。


下载 Wwise 编辑器:

https://www.audiokinetic.com/download/


下载完成后打开,发现这其实是个 Launcher(类似 Cocos Creator 的 DashBoard),在 Launcher 切换 Wwise 页签可以下载新版的 Wwise 编辑器。



特别提醒:对应版本编辑器安装目录包含了 Wwise 的 SDK 和示例工程。



点击对应版本的 Launch 可以打开真正的 Wwise 编辑器,创建一个 Wwise 工程。



创建界面如下:



OK,到这里,准备工作就做好了,当然还有两个比较有用的网址一定要记住去白嫖↓


官方 SDK 文档 :

https://www.audiokinetic.com/zh/library/edge/?source=SDK&id=index.htm

基础视频教程:

https://space.bilibili.com/17571301/video


SDK 接入


Cocos 没有 Wwise 的官方一键集成,并不代表它不支持 Cocos。我们参考一下 DEMO 再结合官方 SDK 做分析:


DEMO

SDK

SoundEngine


参照 cocos2d-x-IntegrationDemo 的 Windows 工程,并对比 Wwise-SDK 和 Wwise-SDK 下 samples 目录里的 SoundEngine 工程,不难得出:


  • 可以集成 Wwise 提供的预编译库到 Cocos 原生工程,Wwise 的所有功能都通过 include 文件夹里的头文件暴露;

  • Wwise 本身不提供文件路径定位的功能,需要实现对应 Wwise 申明的抽象接口,并注册给 Wwise 使用,并且 iOS、Android、Windows 的实现不一样。不过 SoundEngine 基本给我们实现的七七八八了,我们只需要考虑 Cocos Creator 原生端的热更新+文件名与 UUID 的映射;

  • 我们可以自己封装一个 Wwise 的单实例管理器去管理 Wwise 的生命周期,以及封装加载、播放、暂停等接口,并通过 jsb 暴露给 js 调用,方便逻辑开发。


下面是我在 Cocos Creator 的 native 项目下建立的目录:



  • include 来自 {wwise-sdk}/include

  • prebuilt 为新建文件夹,里面放置各个平台的预编译库(来自 Wwise-SDK)

  • proj.xxx 为各平台的工程配置文件

  • WWiseHelper 为一个单实例的 Wwise 管理器,代码可以先复制 cocos2dx-IntegrationDemo 的 WwiseWrapper

  • 其余都来自 {wwise-sdk}/samples/SoundEngine


我们先来编译 Windows、Android、iOS 的 SDK,之后再看看如何让它顺利运行起来。


SDK-Windows


用 VS 打开 Cocos 的 sln 工程,新建一个 libwwise 工程,并为入口项目设置依赖项:



libwwise 的各个配置我们先完全参考 libcocos2d 的配置, libwwise 增加目录包含:



game 工程也添加目录包含:



game 工程增加链接库文件目录和相应的 lib 文件名:



libwwise 工程将 win32 和 common 的代码文件加入进来,把 WWiseHelper 也加入进来:



修改掉一些编译报错和一些代码报错,Windows 基本就编通了。


SDK-Android


安卓的 jni 编译,需要编写 mk 文件, 参考 cocos2dx-IntegrationDemo 的写法,基本能满足需求:



不过为了工程化管理,笔者单独写了 mk 文件,给主工程引用,方便管理,内容与 Demo 的大同小异:



SDK-iOS


iOS 工程下我们同样建立一个 lib 工程,把文件和 lib 库都加入进去:



SDK-WWiseHelper


把 Wwise 库编译进去后,接下来我们介绍怎么使用。


在使用前,我们至少要先准备一些简单的 Wwise 资源,方便 runtime 调用。


打开 Wwise 编辑器新建一个工程,把一个 wav 频拖入进去:



右键这个音频,New Event->Play:



切换到 SundBanks,我们新建一个 Main 的 bnk:



在菜单的 Layouts 切换 SoundBnk,然后把 Play_ttt 事件拖动给 Main-bnk,点击 Generate,发布成功:



按照官方 SDK 文档介绍,Wwise 的 runtime 只会用到 Init.bnk 和 Main.bnk。我们只需要调用 Wwise 的接口发送 Play_ttt 的事件,那么游戏就会播放这个音频。


回过头来看 WWisehelper,我们之前只是简单 copy 了 cocos2dx-IntegrationDemo 的内容。



只提供了初始化,销毁,每帧调用 render 的参考代码。别的嘞?没关系,官方的 SDK 提供了完整的资料,看完官方文档,在查阅  SDK 的头文件,不难发现,基本的 API 都在这里:



所以我们可以根据这些 API,扩展下 WWiseHelper:



基本功能就是加载卸载 bnk、注册 object、发送 event、暂停、继续、停止、rtpc 控制等。


在 game 的 AppDelegate 中需要加入 Wwise 的生命周期管理(暂停,继续,销毁)


注:plugin 命名空间就不用 care 了,这是我们的所有扩展库的命名空间。


通过 jsb-binding 导出给 js 端调用(你们都会的):



在 ts 端新建的 d.ts 添加接口申明:



在 ts 中再次封装一个 player 类,初始化的时候,加载2个 bnk,就可以调用 postEvent 播放了:



SDK-兼容 Cocos Creator

的资源管理方式


然而,当你做完上面的所有步骤,你会发现可能还是不能正确播放,看 log 会发现 Wwise 报错显示未找到 Init.bnk Main.bnk


原因很简单,因为当你把资源放到 Creator 编辑器下的 assets 目录后,经过 Creator 发布打包后,所有资源都会被重命名为 uuid 形式放在 Cocos 的 bundle 下的 native 目录。


想解决这个问题有两种方式:


  • 方法一:自建资源目录,这个目录不放在在 assets 目录,打包后也不归 bundle 管理。

  • 方法二:把 uuid 和原文件名关联隐射,读取时把原文件名转化为真正的 uuid。


第一种比较简单,没什么挑战,所以不介绍了,我们介绍第二种(我们就是喜欢挑战最难的),下面为实现方式:


  1. 假设将整个 Wwise 工程导出的内容都放在 resouce-bundle 下,那么我们建立一个 resouces/bnk 文件夹(如果在别的 bundle 下同理)。

  2. 新建一个 bnk.txt 放到上面目录中。

  3. 在 bnk.txt 里记录所有 bnk 和 wem(wem 为单独未合并音频-可在官网 SDK 文档查看)文件对应的 uuid 文件名。

  4. bnk.txt 的内容可以通过 Creator 插件模式自动监听文件变化生成,uuid 直接读取 .meta 为文件里的即可。

  5. 初始化 Wwise 时,先获取 resouces-bundle 的 native 路径,再把 bnk.txt 中记录的隐射关系传给 Wwise,那么所有的 Wwise 导出文件都能根据 uuid 直接获得在 resouce-bundle 的 native 文件夹下的实际相对路径。

  6. 获取的 uuid 路径再通过 cocos2d::FileUtils::getInstance()->fullPathForFilename 得到最后热更新最新版本的路径。

  7. Android 版在 Cocos 会得出 @assets/ 前缀的路径,代表的是包内内容,需要通过 Android 的 AssetManager 读取,读取时(Wwise 有自己的读取文件函数封装),需要把 @assets/ 前缀去除,需要特殊处理下资源路径图:


iOS+Windows 关键代码:



Android 关键代码:



当你准备好这些,并且全部编译通过,打包到手机上,就能正确听到 Wwise 的音效输出了,真的很丝滑有没有。


*本文源自「乐府札记」公众号




📢📢Cocos Star Meetings「杭州站」报名开启!11月6日(本周六)下午14:30,我们在杭州网易大厦二期等待各位!独立游戏开发者 阿信OL、「Star Writer」异名、每日给力主程陈炫烨为大家准备了满满游戏开发干货,还有 Cocos 生态总监大表姐、网易易盾李鹤仙空降现场!活动限额80人,点击文末【阅读原文】或扫码报名吧↓



往期精彩

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存