之前写过一个用语音转文本的方法来检测关键词。
LLM语音交互:Unity语音交互——关键词检测篇。(新手入门)_llm unity-CSDN博客
但是语音转文字本身需要账号,而且会占用一定的运行速度。
这次主要是看了一篇官方的文档,发现了一个官方自带的关键词检测功能。
Unity 中的语音输入 - Mixed Reality | Microsoft Learn
这里,给大家贴上我的原始代码:
using UnityEngine;
using UnityEngine.Windows.Speech;
using System.Collections.Generic;
using System.Linq;
public class SpeechKeywords : MonoBehaviour
{
// 关键词识别器
private KeywordRecognizer keywordRecognizer;
public TextToSpeech textToSpeech;
// 存储关键词和对应的操作
private Dictionary<string, System.Action> keywords = new Dictionary<string, System.Action>();
void Start()
{
keywords.Add("你好", () =>
{
Answer2Log("你好!");
});
keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray());
keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;
keywordRecognizer.Start();
}
private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args)
{
System.Action keywordAction;
if (keywords.TryGetValue(args.text, out keywordAction))
{
keywordAction.Invoke();
}
}
public void Answer2Log(string aText)
{
string answerText = aText;
textToSpeech.ConvertTextToSpeech(answerText);
string modifiedText = "robot:" + "\n" + answerText + "\n";
}
void OnApplicationQuit()
{
// 停止并释放识别器资源
if (keywordRecognizer != null && keywordRecognizer.IsRunning)
{
keywordRecognizer.Stop();
keywordRecognizer.Dispose();
}
}
}
//在这里面添加关键词以及调用的方法就行。
keywords.Add("你好", () =>
{Answer2Log("你好!");
});
//当然,我照例附上我的优化后的代码,这样就可以在编辑器里面设置关键词和方法了。
using UnityEngine;
using UnityEngine.Windows.Speech;
using UnityEngine.Events;
using System.Collections.Generic;
using System.Linq;
public class SpeechKeywords : MonoBehaviour
{
// 关键词识别器
private KeywordRecognizer keywordRecognizer;
public TextToSpeech textToSpeech;
// 用于在Unity编辑器中填写关键词内容和触发的事件
[System.Serializable]
public class KeywordAction
{
public string keyword;
public string response;
public UnityEvent responseEvent;
}
public KeywordAction[] keywordActions;
// 存储关键词和对应的操作
private Dictionary<string, System.Action> keywords = new Dictionary<string, System.Action>();
void Start()
{
foreach (var keywordAction in keywordActions)
{
// 添加关键词和对应的操作到字典中
keywords.Add(keywordAction.keyword, () =>
{
Answer2Log(keywordAction.response);
keywordAction.responseEvent.Invoke();
});
}
keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray());
keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;
keywordRecognizer.Start();
}
private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args)
{
System.Action keywordAction;
if (keywords.TryGetValue(args.text, out keywordAction))
{
keywordAction.Invoke();
}
}
public void Answer2Log(string aText)
{
string answerText = aText;
textToSpeech.ConvertTextToSpeech(answerText);
}
void OnApplicationQuit()
{
// 停止并释放识别器资源
if (keywordRecognizer != null && keywordRecognizer.IsRunning)
{
keywordRecognizer.Stop();
keywordRecognizer.Dispose();
}
}
}
我照例设置了关键词、回复词、触发函数三个内容。
问题总结:
我试过了,这个关键词检测的方法和官方案例中的是同一个,都存在一个问题,当关键词为中文是,在Unity中可以正常运行,但是投影到Hololens就会报错。
后来官方给了一个听写的功能:
using UnityEngine;
using UnityEngine.Windows.Speech;
using UnityEngine.Events;
using System.Collections.Generic;
[System.Serializable]
public class KeywordAction
{
public string keyword;
public UnityEvent action;
}
public class DictationScript : MonoBehaviour
{
private DictationRecognizer dictationRecognizer;
[Tooltip("配置关键词和对应的UnityEvent")]
public List<KeywordAction> keywordActions;
void Start()
{
dictationRecognizer = new DictationRecognizer();
// 订阅 DictationResult 事件
dictationRecognizer.DictationResult += DictationRecognizer_DictationResult;
dictationRecognizer.Start();
}
void OnDestroy()
{
// 停止听写识别
dictationRecognizer.Stop();
// 取消订阅事件并释放 DictationRecognizer
dictationRecognizer.DictationResult -= DictationRecognizer_DictationResult;
dictationRecognizer.Dispose();
}
// DictationResult 回调
private void DictationRecognizer_DictationResult(string text, ConfidenceLevel confidence)
{
Debug.LogFormat("Dictation result: {0} Confidence: {1}", text, confidence);
// 在这里处理完整识别的字符串
// 检查识别结果中是否包含任何关键词
foreach (var keywordAction in keywordActions)
{
if (text.Contains(keywordAction.keyword))
{
keywordAction.action.Invoke();
break; // 找到匹配的关键词后可以跳出循环,防止多次触发
}
}
}
}
这个功能需要电脑设置支持语音输入:
这个方法可以支持中文识别