做一个记录。

实现的效果为通过麦克风输入简单的指令,让cube动起来。

例如:我说“旋转”,它能旋转;我说“停止”,它就停止。

我使用的版本是unity2019.4.11f1,更高版本的应该也可以,但我没试过。

unity 语音长时间唤醒 unity语音控制操作_右键

首先,创建项目

unity 语音长时间唤醒 unity语音控制操作_右键_02

创建一个平面、物体cube。

unity 语音长时间唤醒 unity语音控制操作_unity 语音长时间唤醒_03

使用动画机相关操作实现动作。

创建Animator Controller动画状态机,右侧Inspector窗口可以改名字,改为cube,挂到cube上面。

unity 语音长时间唤醒 unity语音控制操作_语音识别_04

 

unity 语音长时间唤醒 unity语音控制操作_右键_05

 【ps:如果找不到Animator那俩窗口了,去window里面找。】

unity 语音长时间唤醒 unity语音控制操作_语音识别_06

创建state。橙色块为启动后自动跳的第一个状态,即默认状态。也就是说启动后Entry→idle是无条件转换的。

Entry和橙色状态之间的转换不能删除,一开始就跳到橙色块的状态。所以要设置为静止状态。如果将橙色块直接设置旋转状态,那么一运行就自动跳到这里了,小球开局即跳,语音指令就没有意义了。

【可以通过右键灰色状态块,Set As Layer Default State 将该状态设置为默认状态。这里的设置都是灵活、不唯一的,我只记录我的过程。】

unity 语音长时间唤醒 unity语音控制操作_右键_07

再创建一个空的State,改名为Rotate,表示旋转状态。

unity 语音长时间唤醒 unity语音控制操作_unity 语音长时间唤醒_08

创建动画Animator,改名为Rotate。

unity 语音长时间唤醒 unity语音控制操作_unity 语音长时间唤醒_09

将动画Rotate挂到状态Rotate上:

①点击灰色块Rotate

②点击动画Rotate,不要松鼠标

③将动画Rotate拖到状态Rotate的Motion属性上。

unity 语音长时间唤醒 unity语音控制操作_unity_10

拖好的效果。

unity 语音长时间唤醒 unity语音控制操作_右键_11

这时我们回到Scene窗口,点击cube,在Animation窗口创建Property,我们这里想实现的效果是旋转,所以在Transform里面找Rotation。

unity 语音长时间唤醒 unity语音控制操作_System_12

给cube设置跳跃的动作:

①左侧可以展开

②、③添加关键帧

④让cube绕y轴转360°

⑤点击播放可以查看效果。

unity 语音长时间唤醒 unity语音控制操作_unity 语音长时间唤醒_13

状态的转换。回到Animator窗口,右键idle,Make Transition到Rotate。表示由idle静止状态到Rotate旋转状态的转换。

unity 语音长时间唤醒 unity语音控制操作_语音识别_14

这里需要一个参数来判断转不转换。是布尔类型的。

unity 语音长时间唤醒 unity语音控制操作_语音识别_15

改名为Rotating。

unity 语音长时间唤醒 unity语音控制操作_unity_16

 右键单击idle,添加从idle到Rotate的转换。

unity 语音长时间唤醒 unity语音控制操作_右键_17

同样添加从Rotate到idle的转换。

unity 语音长时间唤醒 unity语音控制操作_语音识别_18

添加转换条件,当参数Rotating 为true时,发生从idle到Rotate的转换。

unity 语音长时间唤醒 unity语音控制操作_unity 语音长时间唤醒_19

从Rotate到idle同理,设为false。

unity 语音长时间唤醒 unity语音控制操作_右键_20

然后就到代码部分了。因为之前没基础,也是查了很多资料,参考了各路大神的代码。

创建C#脚本。【我习惯放到文件夹里】

unity 语音长时间唤醒 unity语音控制操作_unity 语音长时间唤醒_21

下面是完整代码。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Windows.Speech;

public class SpeechInteraction : MonoBehaviour
{
    //一些必要的定义
    private KeywordRecognizer keywordRecognizer;//单词识别器
    private Dictionary<string, Action> actions = new Dictionary<string, Action>();//创建一个字典并初始化【必须初始化】,实现string和Action的配对。
    Animator animator;//动画机

    // Start is called before the first frame update
    void Start()
    {
        actions.Add("旋转",Rotate);//注册配对,说“旋转”对应Rotate函数。
        actions.Add("停止",Stop);//说“停止”对应Stop函数。
       
        //监听语音输入,并尝试将说出的短语与注册关键字列表匹配
        keywordRecognizer = new KeywordRecognizer(actions.Keys.ToArray()); 
        keywordRecognizer.OnPhraseRecognized += Recognizedspeech;
        keywordRecognizer.Start();

        //动画机
        animator = this.transform.GetComponent<Animator>();
    }

    private void Recognizedspeech(PhraseRecognizedEventArgs speech)//把识别到的语句打印出来
    {
        Debug.Log(speech.text);
        actions[speech.text].Invoke();
    }

    private void Rotate()//旋转
    {
        animator.SetBool("Rotating", true);//Rotating为状态转换参数
    }
    private void Stop()//停止
    {
        animator.SetBool("Rotating", false);
    }
}

官方关于KeywordRecognizer的手册:Windows.Speech.KeywordRecognizer - Unity 脚本 API

里面说仅在 Windows 10 上可用,我是win11也可以的。

测试结果:

说“旋转”:是可以动起来的。

unity 语音长时间唤醒 unity语音控制操作_语音识别_22

说“停止”:是会停的。 

unity 语音长时间唤醒 unity语音控制操作_unity_23

控制台:

unity 语音长时间唤醒 unity语音控制操作_右键_24