声控游戏,关键字识别,语音识别
一,声控游戏
声控游戏的关键就在于声控二字,角色的控制在勇士传说的学习中已经用到了很多。而声音的输入还是头一次遇见。
跟着b站up的学习一下正片_哔哩哔哩_bilibili
声音的输入主要是利用到了Microphone。附上unity的官方文档Unity - Scripting API: Microphone (unity3d.com)
通过这个我们可以用麦克风录制一段音频然后储存在AudioClip里面。
实现思路
在麦克风录制的时候,每帧都在音频中切一小段,获取当前这段音频最大的音量。在update中获取最大音量并实时更新。
需要注意的是不同的设备、麦克风的声音大小是不同的,用来在游戏时调整合适的输入值以保证游戏的流畅,不同设备之间的适配目前没有想到好的解决方法
开始录制的方法
//开始录音,device麦克风名称;loop循环录制;lengthSec录制长度;frequency频率啥的,这里的44100是默认值
micRecord = Microphone.Start(device, true, 999, 44100);
使用设备开始录制。如果为设备名称传递 null 或空字符串,则将使用默认麦克风。您可以从 devices 属性获取可用麦克风设备的列表。可以使用 GetDeviceCaps 属性查找麦克风支持的采样率范围。
要注意,如果要在 Web 播放器中使用 Microphone 类,则需要获取 用户的许可。调用前调用 Application.RequestUserAuthorization 任何 Microphone 方法
官方代码
手写一个函数来实现获取最大音量
float GetMaxVolume()
{
float maxVolume = 0f;
float[] volumeData = new float[128];
int offset = Microphone.GetPosition(device) - 128 + 1;
if (offset < 0)
{
return 0;
}
micRecord.GetData(volumeData, offset);
for (int i = 0; i < volumeData.Length; i++)
{
float tempMax = volumeData[i];
if (tempMax > maxVolume)
{
maxVolume = tempMax;
}
}
return maxVolume;
}
就是从offset位置开始,获取一段录音的数据并存放到volumeData数组中,然后便利数组通过比较找到最大值,然后把最大值传递给音量。
获取到最大音量之后就是常规操作了,利用这个志进行操作就行。可以扩展出很多用法。目前用最大值和常量进行比较,分成三个阶段,在一阶段中不动,在二阶段进行前进操作,在三阶段前进和跳越同时进行。因为跳跃的力每帧都在叠加,所以用time写一个内置cd,限制跳跃。
二,关键字识别
在查找资料的过程中得知unity本身就带有一个库,可能实现关键词的语音识别,也就是UnityEngine.Windows.Speech这个库,是可以做到设定关键词,然后通过语音识别,判断是否说的是设定的关键词。有了这个就可以制作关键词识别了。当然这里要注意,这个库只能在windows平台使用。
DictationRecognizer
官方链接Windows.Speech.DictationRecognizer - Unity 脚本 API
需要引入命名空间using UnityEngine.Windows.Speech;
关于DictationRecognizer的描述为 DictationRecognizer监听语音输入,并尝试确定说出的短语。用户可以注册和监听假设和短语完成事件。Start() 和 Stop() 方法分别用于启用和禁用听写识别。用完识别器后,必须使用 Dispose() 方法对它进行处置以释放它使用的资源。它将在垃圾收集期间自动释放这些资源,如果资源没有在这之前得到释放,将会产生额外的性能成本。
使用方面,用字符串数组来存储关键字,再创建一个关键字识别器
//创建一个关键字识别器
m_Recognizer = new KeywordRecognizer(m_Keywords);
Debug.Log("创建识别器成功");
m_Recognizer.OnPhraseRecognized += OnPhraseRecognized;
用Start可以开始识别对话。
用Stop结束听写识别会话。
写一个监听方法,如果监听到关键字就进行处理。
识别器的监听方法,当时别到声明的关键字时的回调函数
private void M_RecognitionListener(PhraseRecognizedEventArgs args)
{
//打印识别到的文本
Debug.Log(args.text);
}
通过官方文档得知使用过后如果不释放会有额外的性能消耗
private void OnDestroy()
{
//判断是否有语音识别器,如果有,则释放
if (mPhraseRecognizer != null)
{
//用完应该释放,否则会带来额外的开销
mPhraseRecognizer.Dispose();
}
}
手动释放。
要注意一点的是,这个关键词识别库,似乎的用识别出来的字符串与关键词数组进行较,相同才判断识别成功。一句话里包含关键词,没能检测出来的。
三,语音识别
据了解可以通过讯飞和百度AI实现
讯飞的实现方法暂时没了解,百度的实现是再b站上学习的用unity实现百度语音识别_哔哩哔哩_bilibili
目前理解的也不是很深入,依葫芦画瓢过了一遍。
钩锁效果
基本思路是发射射线,检测到物体的时候挂上一个springjoint组件,然后用linerenderer渲染角色和目标点之间的连线。
Unity - 脚本 API:SpringJoint2D (unity3d.com)
SpringJointunity游戏引擎中的一个组件,用于将两个 2D 物体连接起来,并模拟它们之间的弹簧效果。它可以在游戏中模拟很多物理效果,例如弹簧、绳索、悬挂等等。
基本参数:
connectedBody:要连接的物体的刚体组件;
distance:弹簧的初始长度;
dampingRatio:阻尼比,用于控制弹簧的震荡;
frequency:弹簧的弹性系数;
autoConfigureDistance:是否自动计算弹簧的初始长度;
anchor 和 connectedAnchor:弹簧的两个连接点在物体上的坐标。
Line Renderer component
官方文档Line Renderer component - Unity 手册 (unity3d.com)
线渲染器 (Line Renderer)
组件采用 3D 空间中两个或多个点的数组,在每个点之间绘制一条直线。可以使用线渲染器 (Line Renderer) 来绘制从简单直线到复杂螺旋线的任何线条。这条线始终是连续的;如果需要绘制两条或更多完全独立的线,则应使用多个游戏对象,每个游戏对象都要有自己的线渲染器 (Line Renderer)。线渲染器 (Line Renderer) 不渲染宽度以像素为单位的线。它会渲染宽度以世界单位为单位的多边形。线渲染器 (Line Renderer) 使用与轨迹渲染器 (Trail Renderer) 相同的线渲染算法。
线渲染器的创建
要创建线渲染器,请执行以下操作:
- 在 Unity 菜单栏中,选择 GameObject > Effects > Line。
- 选择 Line Renderer 游戏对象。
- 通过在 Inspector 窗口中直接设置数组值或使用 Create Points 场景编辑模式,可以将点添加到 Line Renderer 的 Positions 数组中。
- 使用 Inspector 窗口配置线条的颜色、宽度和其他显示设置。
线渲染器材质 (Line Renderer Materials)
默认情况下,线渲染器 (Line Renderer) 使用内置材质 Default-Line。您可以更改线条的外观而无需更改此材质,例如编辑线条的颜色渐变或宽度。
对于其他效果,例如在线条上应用纹理,需要使用其他材质。如果您不想为新材质编写自己的着色器,可以将 Unity 内置的标准粒子着色器与线渲染器 (Line Renderer) 结合使用。
线渲染器场景编辑模式 (Line Renderer Scene Editing Mode)
可以使用线渲染器 (Line Renderer) 的 Inspector 来更改场景编辑模式。不同的场景编辑模式让您能够以不同的方式使用 Scene 视图和 Inspector 来编辑线渲染器 (Line Renderer)。有三种场景编辑模式:None、Edit Points 和 Create Points。
旅游回来力。附一张照片