移动 > 游戏 > 手游

Cocos Creator 3.x 3D 空间音频解决方案!

170人参与 2024-08-04 手游

介绍

最近在用 cocos creator 3.8 制作一个 3d 联机坦克大战游戏。因为项目需要,在 cocos creator 中实现了 3d 空间音效的方案,在此分享给大家,希望能对大家有所帮助。


背景

在 3d 游戏中,合理搭配音效元素,可以显著提升游戏沉浸感。利用双通道管线和自定义音频混合创建具有 3d 空间效果的音频,已经被用于大部分的 3d 游戏场景,尤其是 fps 类游戏。

在场景中添加具有 3d 效果的脚步声、枪声,玩家即可借助专业的耳机设备,通过 3d 空间音效做到“听声辨位”,从而丰富游戏的玩法。

本篇教程用于引导大家如何在 cocos 中使用浏览器自带 audiocontext api 实现 3d 音效。

详情请参考 mdn 文档:

  • https://developer.mozilla.org/en-us/docs/web/api/web_audio_api/web_audio_spatialization_basics

audiocontext

音频上下文,是一张节点图,将音频模块节点连接在一起,构成音频处理流程图。类似于 shader graph,动画图,如下图所示:

这里并没有提供可视化工具,但在代码中,我们可以通过anode.connect(bnode)的方式来连接所有的音效节点,来达成类似于混合和编排的效果。

想要处理音频,我们首先需要创建一个 audiocontext 实例,代码如下:

this.ac = new audiocontext();

source(音频源)

在 cocos 中,我们推荐以 buffer 的形式获取音频源,这样可以避免创建 html 元素。我们可以利用 cocos 的 audioclip 属性,快速拿到资产库中音频源的 audiobuffer 数据。

代码:

@property({
     type: audioclip,
     displayname: "音频源",
 })
audioclip: audioclip;
//...略
this.source = this.ac.createbuffersource();
this.source.buffer = this.audioclip._player._player._audiobuffer;
this.source.start();

listener(监听者)

在游戏开发中,摄像机是眼睛,那么 listener 就类似于耳朵。大部分情况下我们的场景中仅有一个激活的 listener。

this.listener = this.ac.listener;

和摄像机一样,我们可以设置 listener 的位置和方向。(请注意,这里传给 setorientation 的是 cocos 中节点的 forwardup 向量)。

一般情况下,这里的 listenernode 可以传摄像机的节点(因为眼睛和耳朵的位置很接近)。

对应的就是以摄像机的位置为 listener 的坐标计算空间音频的声道和衰减模型。

代码如下:

  @property({
    type: node,
    displayname: "收听者",
  })
  listenernode: node;
  //...
  this.listener.setorientation(
      this.listenernode.forward.x || 0,
      this.listenernode.forward.y || 0,
      this.listenernode.forward.z || 0,
      this.listenernode.up.x || 0,
      this.listenernode.up.y || 1,
      this.listenernode.up.z || 0
   );

  this.listener.setposition(
      this.listenernode.worldposition.x || 0,
      this.listenernode.worldposition.y || 0,
      this.listenernode.worldposition.z || 0
  );

pannernode (发声节点)

listener 对应,panner 对应的是 3d 空间中的 “发声者”(比如喇叭声、枪声、脚步声)。

常用的参数我们可以设置 panner 的位置(position)、最大距离( maxdistance )等等,代码如下:

@property({
 type: node,
 displayname: "发声者",
})
pannernode: node;

//...略

this.panner = this.ac.createpanner();
this.panner.panningmodel = "equalpower"// 音频空间化算法模型
this.panner.distancemodel = "linear"// 远离时的音量衰减算法
this.panner.maxdistance = this.maxdistance; // 最大距离
this.panner.refdistance = 5// 开始衰减的参考距离
this.panner.rollofffactor = 3// 衰减速度
this.panner.coneinnerangle = 360// 声音360度扩散
this.panner.orientationx.value = 1// 声源朝向x分量
this.panner.orientationy.value = 0;
this.panner.orientationz.value = 0;
this.panner.setposition(
  this.pannernode.worldposition.x,
  this.pannernode.worldposition.y,
  this.pannernode.worldposition.z
);

gainnode(增益节点)

文章的开头我们说过,audiocontext是一张“节点图”,那这里我们就增加一个gainnode(增益节点),增益是一个无单位的值,会对所有输入声道的音频进行相应的增加(相乘)。

此处我们用于修改整体音频的音量大小。gain 修改的效果会影响到 panner 的结果。

举个例子:收音机的音量如果音量很小,那么离太远就听不清了,反之音量很大,那离得很远也能听到。

代码如下:

this.gainnode = this.ac.creategain();
//修改音量
this.gainnode.gain.value = 0.2;

connect(连接)

把我们创建的节点连接起来,用 connect 方法。

this.gainnode.connect(this.ac.destination);
this.gainnode.connect(this.panner);
this.source.connect(this.panner);
this.panner.connect(this.gainnode);

销毁

由于我们是手动创建的音频上下文节点,所以 cocos 并不会在销毁组件的时候自动释放这些音频实例,这可能导致我们已经切换场景了,但上一个场景的音频还在继续播放。

要解决这个问题,我们只需要在组件销毁的生命周期钩子函数 ondestroy 中手动释放我们创建的音频实例即可。

代码如下:

ondestroy() {
  try {
    this.gainnode.disconnect(this.ac.destination);
    this.gainnode.disconnect(this.panner);

    this.source.disconnect(this.panner);
    this.panner.disconnect(this.gainnode);

    this.source.stop();
    this.ac.close();
  } catch (e) {
    console.log(e);
  }
}

源码获取:

点击【阅读原文】或者前往:https://forum.cocos.org/t/topic/156994,可在文中找到本文源码。

以上就是在 cocos 中应用 3d 音效的全部内容,欢迎各位大佬查漏补缺,评论区探讨交流。希望这篇教程能对您的工作提供帮助。

作者介绍

蔬菜土豆泥,前端工程师,来自古城西安,热爱游戏开发,喜欢钻研各种 web 3d 效果,擅长电商互动小游戏和交互式广告的开发与设计。

目前在用 cocos creator 开发 3d 网络游戏,也会不定期分享一些自己的经验心得,希望能够和大家多多交流,共同进步。

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

独立3D网络游戏《战域重甲》开发与上架经验分享

08-04

2024 Cocos 沙龙成都站精彩回顾,八月开启厦门站!

08-04

蜗牛游戏独立游戏分支Wandering Wizard获两款惊悚新游发行权

08-04

Cocos 正式开启全国巡回沙龙,下一站会是哪里呢?

08-04

华为帐号“一号畅玩”体验,助力游戏用户增长

08-04

「Cocos 开发者沙龙@成都站」,6月29日下午14:00,邀您参加!

08-04

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论