最近一直找游戏设计灵感。
找着找着,突然想起,以前玩过的一款打飞机游戏,端游,他可以根据你播放的音乐文件来自动发射子弹,玩家不是能自主发射子弹的,当时我就一直拿那个:《劲乐团》里的一首曲子:《V3》- 贝多芬交响曲。
这首曲子,全程高能,整个屏幕都是子弹,爽啊,哈哈,而且这首曲子也很嗨。
当然与音乐相关的游戏还不止这款。。。
相关游戏:
- 劲舞团(韩国T3 娱乐公司开发,游戏开发技术没有与音乐有关,这游戏只是编辑定时弹出什么QTE的按键序列而已)
- 劲乐团(韩国O2Media游戏公司开发,游戏开发技术应该是用到了声乐文件的音频spectrum图谱的分析,先自动生成一个节奏点相关的QTE数据,然后再人工审核一下生产的内容,可减少开发成本,因为如果全程人工编辑,那个编辑人力成本太高了)
- 节奏大师(同上,腾讯光速工作室开发)
- QQ音速(同上,腾讯代理,韩国seed9开发)
- 某些游戏也会根据我们的音波来加速移动,发射子弹等。这些就不一一介绍了,玩过想过的太多了。
等等,还有现在新出的各式各样的游戏。基本都会使用到先音频分析自动生成数据,再人工调整。(当然,我只是猜测,肯定有团队是全人工编辑的)
为了找灵感,再尝试试API来制作一些功能,再未来开发,也许有帮助。
OK,扯题的话就不说了。
运行总体效果如下图:(没有声音)

录制
Microphone类使用到的几个API
public static string[] devices { get; }
获取可用的麦克风的设备名称数组public static AudioClip Start(string deviceName, bool loop, int lengthSec, int frequency);
使用指定deviceName设备开始录制public static void End(string deviceName);
指定deviceName设备结束录制public static int GetPosition(string deviceName);
获取麦克风当前对应设备写入录制缓存的索引位置public static bool IsRecording(string deviceName);
获取指定deviceName设备名称是否当前录制中
OK,就这么几个是主要的。
录制步骤
- 先检测有没设备
Microphone.devices.Length > 0 - 开始录制调用
Microphone.Start,要传入使用的设备名,是否环形循环录制缓存,录制缓存支持的时长,录制的采样率- 设备名就
Microphone.devices里头其一 - 是否环形循环录制缓存意思就是是否录制数据写到尾部是,是从将写入指标重置会开头(0索引)
- 录制缓存支持的时长,就是如果不是环形循环录制的话,那么录制时间到了,就不会再录制
- 录制采样率,这个决定了录制出来声音的质量,采样率越高当然就越接近原声
- 但采样率不能乱设置,下面会相关的知识点讲到采样率是什么东东
- 设备名就
- 等待录制时间到达,就自动取消录制(或时手动的在时间到达之前结束录制)
- 播放刚刚录制的AudioClip,已测试是否有效。
- 如果听不到声音,请检查:
- 播放该AudioClip的AudioSource的Volume(音量);
- 如果AudioSource的Spatial Blend是2D的,那就确定场景中至少有一个AudioListener组件时启用的。
- 如果AudioSource的Spatial Blend是3D的,那就确定启用的AudioListener与你播放的AudioSource的距离保持在AudioSource的MinDistance与MaxDistance之前。
- 在调用Microphone.Start中的frequency确定是在能听到的范围,一般设置在:1000~44100之间就可以了(小于100的几乎都听不到,之前不小心设置错了Slider.Value的值为1,传了个1过去,导致录制出来的AudioClip没有任何声音)
- 还是听不到,那就确保你的音响设备的音量,与设备是否正常。
- 如果听不到声音,请检查:
相关的知识点
- 声频:指的是声波介质,每秒震动的次数,单位交:赫兹,英文:Hz,人类能听到的声频大概是:20Hz~20000Hz。低于20Hz我们叫超低音声波,高于20000Hz我们叫超高音波(超音波)。而不同物种,他们声频生物传感器是不一样的,如:蝙蝠,相对人类来说的部分超低高音都可以听到,但它能听到的范围也是有限的。
- 声波:而声波是介质震动(一般指的是空气)时的振动波,现实生活中我们听到的声音都是一些连续不间断的声波,声波进入了我们的耳朵(接受声波处理的生物传感器),就听到声音了
- 采样率:因为声波是连续不间断的,但我们记录的是离散的数字信号,采样率就是每秒记录的次数。如:44100次/每秒,就是我们常见的44KHz。但是采样率越高记录所需要的数据量就越大。相反,越低的采样率,数据量就很少了,但是音质会很差,甚至低到一定程度,我们都几乎听不到。我们平时看到保安人员的对讲机,大概就是1KHz,我们一些高音质的MP3等音频文件有16KHz,32KHz,44KHz,都有,有些电影院的那些可能上MHz都是有的。
- 比特率:和采样率差不多的意思,只是他主要表达的是每秒需要记录用到的bit位有多少,考量维度不一样,前者是记录次数,后者是使用bit的量,就可以很准确的确定数据占用量。
音波图(不是声谱Spectrum)
至于声谱图,我没去研究过,这里不涉及。
AudioClip类API
public bool GetData(float[] data, int offsetSamples);
从AudioClip中,指定offsetSamples的位置开始读取音波数据存入我们预先创建的float[] data缓存中。
AudioClip是我们的音频对象。
- Microphone.Start返回的是AudioClip。
- Project视图管理资源中,音频文件也是AudioClip。
而我们就是通过这个AudioClip.GetData来取对应缓存位置记录的音波数据的,然后根据这些数据我们将它用于控制一些粒子特效,或是线条,几何体,颜色变化,等来表现我们的音波图的。
下图就是根据此API制作的简单的音波图。(我放了很多个:RawImage,然后用AudioClip.GetData取出来的数据分别控制他们的宽度,及颜色即可,这首史诗级曲子:EI Dorado也是我非常喜欢的,有兴趣可以听听)

扩展
-
播放器,KTV,KTV评分系统:有些前面哪些功能,起始如果上对各音频文件的编解码处理,你甚至可以制作一些播放器了(在搞一些文件读写就好了),录制的话,你要可以搞个人KTV录制。还可以分析音波与原唱的音波图相似度来评KTV录制结果分数。
-
无时间限制录制文件功能:还有一个,起始还可以写一个无时间长度限制的录音软件。
但是还需要对代码调整(就是判断Microphone.GetPosition差不多到缓存尾部的时候,马上再调用Microphone.Start记录重新录制就好了,再将之前录制的那个AudioClip的数据写入文件流啊,就可以了) -
简单语音录制的聊天系统:游戏,或是应用中的简单语音录制的聊天系统,前面讲了怎么怎么录制,怎么怎么从AudioClip拿数据,还有,下面的Code中,也有显示AudioClip.SetData怎么怎么使用,那么就可以将GetData的float[]转到byte[],在通过Socket的网络传输到服务器,服务器再广播,其他接受的客户端先将byte[]转float[],再就AudioClip.SetData,再AudioSource.Clip = 你的Clip,再AudioSource.Play,完事。
Code
using System;
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// author : jave.lin
/// date : 2020.02.18
/// 测试录制麦克风的各种功能
/// </summary>
public class RecordMicrophoneSoundScript : MonoBehaviour
{
public enum RecordStatusType
{
Unstart,
Recording,
End,
}
public enum RecordErrorType
{
None,
NotFoundDevice,
RecordingError,
}
[Space(10)]
public Text playSoundWaveText;
public AudioClip music;
[Space(10)]
public Text startOrEndRecordBtnText;
public Text statusText;
public Text detailStatusText;
public Text deviceCaptureFreqText;
[Space(10)]
public Dropdown deviceDropdownList;
public Dropdown frequencyDropdownList;
public Slider recordTimeSlider;
public Text recordTimeText;
public Text playProgressText;
public Text recordTimeProgressText;
public Slider playProgressSlider;
public Slider recordTimeProgressSlider;
public Text detailRecordClipText;
[Space(10)]
public Color32 lineLowCol = new Color32(1, 1, 0, 1);

本文探讨了如何在Unity中利用麦克风输入实现音效互动的游戏设计,详细讲解了使用Microphone类API进行声音录制、分析和播放的方法,并展示了如何将音频数据转化为视觉效果。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



