React-three实现3D游戏(三)-空间音频
在一个基本的可交互的3D游戏中,人物和环境是不可或缺的元素。接下来,我们将逐步迭代我们的项目,使其更像一个真正的可交互的3D游戏。
3D模型在线预览提供多种低代码平台3D模型在线预览解决方案,实现了将多种3D模型格式无缝集成到低代码业务表单中。这意味着用户可以在不离开低代码平台的情况下,直接查看和操作3D模型,极大地提升了数据可视化的效果和用户交互体验。
空间音频概述
空间音频,故名思意就是指放置在3d空间场景中的音源,拥有现实中立体声音的特性。 它远小近大,且会被墙壁等障碍物所阻隔。
对于一个立体的游戏世界来说是十分重要的元素,试想在吃鸡类游戏中不能听到逐渐靠近的脚步声,游戏的临场感和现实感就大打折扣!
这是threejs官网的一个示例:link,它很好的表现了空间音频的特性。
核心代码:
你可以看到,它创建了一个“耳朵”(listener)并绑定到了相机上,并将audio元素加载的音频资源加载到positionalAudio。这样当音频播放时,相机这个听众就会因为方位和远近的不同听到不同的音乐效果。也就是所谓的立体音效。
react-three中使用空间音频
react-three/drei 工具库中封装了 PositionalAudio组件专门用来在场景中放置空间音频。它只是对原生three中的PositionalAudio的封装,它支持所有原生的api。
它做了以下事情:
- PositionalAudio被创建后就自动将listener加入到camera了,你不需要显示的创建AudioListener并加入camera中。
- 自动创建audio元素加载并播放音频文件,你不需要显示的创建。
你可以直接把PositionalAudio 放到某个网格或模型中,它会与其在空间上绑定。
这是react-three/drei的官方示例:
项目中添加音乐与音效
添加全局音频
所谓全局音频,是指不需要空间效果的音频,也就是我们在网页中正常看到的音频。它不随着人物的空间变化而变化,但可以在设置中更改音量的大小,如背景音乐等。
这里我们有2个选择:
- 使用空间音频,将此音频绑定在人物身上,类似自带音响的效果。
- 使用正常的audio标签,在网页上播放。
大家可以自行选择,这里我为了一致性使用空间音频。 从网站上寻找到合适的bgm和脚本音效,放入public目录下的audios文件夹中。 修改代码如下:
空间音频失效问题
正常的PositionAudio,会将listener自动添加到camera。随着camera方位的变化听到的音效随之变化。
可Ecctrl库将原来的camera位置始终锁定在[0,0,0]的位置。这导致空间音频功能失效。
我在github上我提出这个issue后。 作者提供的解决方案是重新添加listener,正如上面代码中我将listener添加到了玩家身上。这样随着玩家的移动,空间音频再次生效。
添加环境音效
大家可以自行从网站上寻找到合适的音效,这里我共找了2种环境音效:沙滩边的海浪声、森林的鸟叫声。
将音频资源放入根目录public文件夹下的audios文件夹中。 在models文件夹下新建ambiance.tsx文件,用于存放所有的环境音。
附具体代码如下:
基本使用方式与示例无异。这里我多添加了一个球体网格,并设为透明度0.5,用来查看音源的位置和影响范围,方便调试其位置。
添加了debug参数用来控制球体网格的可见。 你可以更改meshStandardMaterial的color属性,让不同的音源有不同的颜色,更方便调试。
你也可以尝试使用原生three提供的 PositionalAudioHelper 用来辅助调试空间音频。
组件挂载
在models下的index.tsx中挂载组件