【征文计划】Rokid 语音指令开发教程 【包含工程源码 和体验包APK】

复制代码

各位开发者大家好!欢迎来到Rokid开发者社区的实战教程专栏。

你是否曾想过让你的Rokid设备在无网环境下依然"耳聪舌辩"?是否希望用户的每一条指令都能得到毫秒级的响应,且隐私绝对安全?离线语音识别(ASR)技术正是你的不二之选。

本期教程,我们将深入 "功能解析所" ,拆解Rokid离线语音的技术内核;分享 "实战经验库" 中的宝贵避坑指南;最后带你闯入 "创意孵化器",实现一个完整的创意Demo。无论你是新手还是老鸟,都能有所收获!
工程源码和安装包体验包在文章末尾

Rokid开发教程 -离线语音指令识别

第一部分:【功能解析所】离线语音,到底是如何工作的?

在开始编码前,理解原理至关重要。Rokid的离线语音指令并非简单的"关键词匹配",而是一个精巧的流程:

  • 语音唤醒(Wake-up): 设备持续监听环境音,通过内置的唤醒词引擎(如"若琪")识别特定关键词,从而从休眠状态进入指令接收状态。
  • 语音端点检测(VAD): 唤醒后,VAD模块会精确判断用户什么时候开始说话,什么时候结束,从而截取出有效的语音片段。
  • 离线语音识别(ASR): 这是核心环节。截取的语音片段会被送入本地的语音识别引擎。该引擎基于预加载的语法网络(Grammar) 进行识别。语法网络就像一个本地的"指令库",定义了所有可能被识别的词条组合,极大提高了识别的准确率和效率。
  • 语义理解(NLU)与执行: 识别出的文本会交给NLU模块解析出用户的意图(Intent)和参数(Slots),最终触发你预先编写好的回调函数来执行操作。

为什么选择离线?

  • 超低延迟: 无需网络传输,响应速度极快(毫秒级)。
  • 隐私安全: 语音数据完全在设备端处理,永不泄露。
  • 稳定可靠: 不依赖网络状态,在飞机、地下室、偏远地区等场景下依然可用。

第二部分:【实战经验库】轻松上手

大家可以使用官方的 XR Interaction Toolkit Plugin(OpenXR)或者UXR3.0 的SDK ,这里我使用的XR Interaction Toolkit Plugin作为教程。环境配置阶段这里我就跳过了,如果还不太了解的话可以看一下官方的这个文档进行配置下SDK以下地址

https://custom.rokid.com/prod/rokid_web/c88be4bcde4c42c0b8b53409e1fa1701/pc/cn/9f40ac8d948545bb8e0b4d3c6fea411f.html?documentId=b55382f9e2df4672834042f360e1852a

更为详细的离线语音配置也可参考Rokid 官方提供的文档 https://custom.rokid.com/prod/rokid_web/c88be4bcde4c42c0b8b53409e1fa1701/pc/cn/9f40ac8d948545bb8e0b4d3c6fea411f.html?documentId=de7df0fb21184266aa22d66636e26a8d

https://custom.rokid.com/prod/rokid_web/c88be4bcde4c42c0b8b53409e1fa1701/pc/cn/9f40ac8d948545bb8e0b4d3c6fea411f.html?documentId=de7df0fb21184266aa22d66636e26a8d

    • 在 Unity 中点击 Assets > Import Package > Custom Package
    • 选择 UXRForOpenXR.unitypackage 并导入所有内容
  • 启用自定义 Gradle 模板

这里可以使用提前供配置好的包Plugins.unitypackage

  • 创建离线语音交互脚本

    using Rokid.UXR.Module; // Rokid UXR语音模块
    using UnityEngine;
    using UnityEngine.Android; // Android权限管理
    using UnityEngine.UI; // UI组件

    // 语音控制脚本 - 处理语音指令来控制物体的颜色变化和旋转
    // 支持的功能:
    // 1. 颜色控制:变成蓝色、变成绿色、随机颜色
    // 2. 旋转控制:开始旋转、停止旋转(绕Y轴)
    // 3. 重置功能:恢复初始颜色和角度
    public class VoiceCommand : MonoBehaviour
    {
    #region 私有变量

    // 语音模块是否已初始化的标志
    private bool isInitialized;

    // 当前是否正在旋转的状态标志
    private bool isRotating = false;

    // 保存物体的初始颜色,用于重置功能
    private Color originalColor;

    // 保存物体的初始旋转角度,用于重置功能
    private Vector3 originalRotation;
    #endregion

    #region 公共变量(在Inspector中设置)

    // 显示接收到的语音指令的UI文本组件
    public Text infoText;

    // 需要改变颜色的物体的渲染器组件
    public Renderer m_Render;

    // 需要旋转的物体的Transform组件
    public Transform m_transform;

    // 旋转速度(度/秒)- 可在Inspector中调整
    [Header("旋转设置")]
    [Tooltip("物体绕Y轴旋转的速度,单位:度/秒")]
    public float rotationSpeed = 90f;
    #endregion
    #region Unity生命周期方法

    // Unity Awake方法 - 在对象创建时调用
    // 用于请求Android录音权限,语音识别需要此权限
    private void Awake()
    {
    // 检查是否有录音权限,没有则请求权限
    if (!Permission.HasUserAuthorizedPermission("android.permission.RECORD_AUDIO"))
    {
    Permission.RequestUserPermission("android.permission.RECORD_AUDIO");
    }
    }

    // 用于初始化语音控制系统和保存物体的初始状态
    void Start()
    {
    // 保存物体的初始状态,用于重置功能
    if (m_Render != null)
    {
    originalColor = m_Render.material.color; // 保存初始颜色
    }
    originalRotation = m_transform.eulerAngles; // 保存初始旋转角度

    复制代码
          // 初始化语音控制系统

    InitializeVoiceControl();
    // 添加语音指令
    AddInstruct();
    }

    void Update()
    {
    // 如果旋转标志为true,则持续绕Y轴旋转
    if (isRotating)
    {
    // 使用Time.deltaTime确保旋转速度不受帧率影响
    // 参数:(x轴旋转, y轴旋转, z轴旋转)
    m_transform.Rotate(0, rotationSpeed * Time.deltaTime, 0);
    }
    }

    复制代码
      // Unity OnDestroy方法 - 在对象销毁时调用
      // 用于清理语音指令和释放资源

    private void OnDestroy()
    {
    // 清除所有已注册的语音指令
    OfflineVoiceModule.Instance.ClearAllInstruct();
    // 提交更改
    OfflineVoiceModule.Instance.Commit();
    }
    #endregion

    复制代码
      #region 语音指令管理
    
      // 添加语音指令到语音识别系统
      // 注册所有支持的中文和英文语音指令

    void AddInstruct()
    {
    // 确保语音模块已初始化
    if (isInitialized)
    {
    // 注册中文语音指令
    // 参数说明:(语言, 显示文本, 拼音, 目标GameObject名称, 回调方法名)

    复制代码
              // 颜色控制指令

    OfflineVoiceModule.Instance.AddInstruct(LANGUAGE.CHINESE, "变成蓝色", "bian cheng lan se", this.gameObject.name, "OnReceive");
    OfflineVoiceModule.Instance.AddInstruct(LANGUAGE.CHINESE, "变成绿色", "bian cheng lv se", this.gameObject.name, "OnReceive");
    OfflineVoiceModule.Instance.AddInstruct(LANGUAGE.CHINESE, "随机颜色", "sui ji yan se", this.gameObject.name, "OnReceive");

    复制代码
              // 旋转控制指令

    OfflineVoiceModule.Instance.AddInstruct(LANGUAGE.CHINESE, "开始旋转", "kai shi xuan zhuan", this.gameObject.name, "OnReceive");
    OfflineVoiceModule.Instance.AddInstruct(LANGUAGE.CHINESE, "停止旋转", "ting zhi xuan zhuan", this.gameObject.name, "OnReceive");

    复制代码
              // 重置指令

    OfflineVoiceModule.Instance.AddInstruct(LANGUAGE.CHINESE, "重置", "chong zhi", this.gameObject.name, "OnReceive");

    复制代码
              // 注册英文语音指令(部分功能)

    OfflineVoiceModule.Instance.AddInstruct(LANGUAGE.ENGLISH, "Show blue", "show blue", this.gameObject.name, "OnReceive");
    OfflineVoiceModule.Instance.AddInstruct(LANGUAGE.ENGLISH, "Show green", "show green", this.gameObject.name, "OnReceive");

    复制代码
              // 提交所有指令到语音识别系统

    OfflineVoiceModule.Instance.Commit();
    }
    }

    复制代码
      // 语音指令接收回调方法
      // 当语音识别系统识别到注册的指令时会调用此方法

    void OnReceive(string msg)
    {
    // 在UI上显示接收到的语音指令
    infoText.text = msg;
    // 在控制台输出日志
    Debug.Log("-RKX- UXR-Sample:: On Voice Response received : " + msg);

    复制代码
          // 根据不同的语音指令执行相应的功能
    
          // 颜色控制指令处理

    if (string.Equals("变成蓝色", msg) || string.Equals("Show blue", msg))
    {
    // 将物体颜色设置为蓝色
    m_Render.material.color = Color.blue;
    }
    else if (string.Equals("变成绿色", msg) || string.Equals("Show green", msg))
    {
    // 将物体颜色设置为绿色
    m_Render.material.color = Color.green;
    }
    else if (string.Equals("随机颜色", msg))
    {
    // 生成随机颜色,确保透明度为1(完全不透明)
    // 使用Random.Range(0f, 1f)生成0-1之间的随机RGB值
    m_Render.material.color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f), 1f);
    }

    复制代码
          // 旋转控制指令处理

    else if (string.Equals("开始旋转", msg))
    {
    // 启动旋转标志,物体将在Update方法中持续旋转
    isRotating = true;
    Debug.Log("开始Y轴旋转");
    }
    else if (string.Equals("停止旋转", msg))
    {
    // 停止旋转标志,物体将停止旋转但保持当前角度
    isRotating = false;
    Debug.Log("停止旋转");
    }

    复制代码
          // 重置功能指令处理

    else if (string.Equals("重置", msg))
    {
    // 停止旋转
    isRotating = false;

    复制代码
              // 重置物体角度到初始状态

    m_transform.eulerAngles = originalRotation;

    复制代码
              // 重置物体颜色到初始状态

    if (m_Render != null)
    {
    m_Render.material.color = originalColor;
    }

    Debug.Log("重置完成:颜色和角度已恢复到初始状态");
    }
    else
    {
    // 处理未识别的指令
    Debug.Log("voice OnResponse: " + msg);
    }
    }
    #endregion
    #region 语音模块初始化

    复制代码
      // 初始化语音控制模块
      // 注册Rokid语音命令助手模块并设置语言为中文

    private void InitializeVoiceControl()
    {
    // 防止重复初始化
    if (!isInitialized)
    {
    // 注册Rokid语音命令助手模块
    // 参数:模块名称,是否为必需模块
    ModuleManager.Instance.RegistModule("com.rokid.voicecommand.VoiceCommandHelper", false);

    复制代码
              // 设置语音识别语言为中文

    OfflineVoiceModule.Instance.ChangeVoiceCommandLanguage(LANGUAGE.CHINESE);

    复制代码
              // 标记为已初始化

    isInitialized = true;
    }
    }
    #endregion
    }

场景创建空物体挂载脚本,添加用于显示的文本,控制颜色旋转的模型,

这里我把unity 工程也上传一份

RokidXRI3.zip (源码)

发布APK 包

RokidAudio.apk

相关推荐
小剑修15 小时前
2025.10.18 复习
unity
渡我白衣21 小时前
《未来的 AI 操作系统(四)——AgentOS 的内核设计:调度、记忆与自我反思机制》
人工智能·深度学习·机器学习·语言模型·数据挖掘·人机交互·语音识别
从孑开始1 天前
ManySpeech.MoonshineAsr 使用指南
人工智能·ai·c#·.net·私有化部署·语音识别·onnx·asr·moonshine
涛涛讲AI1 天前
一段音频多段字幕,让音频能够流畅自然对应字幕 AI生成视频,扣子生成剪映视频草稿
人工智能·音视频·语音识别
beckyye1 天前
阿里云智能语音简单使用:语音识别
前端·语音识别·录音
future_studio2 天前
聊聊 Unity(小白专享、C# 小程序 之 播放器)
unity·小程序·c#
小Tomkk2 天前
Rokid 开发空间小程序 实战
3d·小程序·rokid·jsar
向宇it2 天前
【unity实战】MapMagic 2实战例子
游戏·3d·unity·c#·游戏引擎
SlowFeather2 天前
Unity TMP可控角度多色渐变文字
unity·游戏引擎