引言

在聊手势识别前,咱们先搞清楚:Rokid是谁?它为啥能把AR手势做得这么自然?

Rokid是国内AR(增强现实)领域的“老兵”了,从2014年成立就盯着一个目标——让AR走进日常。你可能见过它的产品:能戴在脸上的“AR眼镜”Max Pro、能揣在兜里的“AR主机”Station 2、适合专业场景的“Station Pro”,这些设备不是用来“炫技”的,而是想让咱们摆脱手机、手柄的束缚,直接用手“摸”虚拟东西。

而手势识别,就是Rokid给AR设备装的“最自然的遥控器”——比如调大虚拟屏幕像捏橡皮一样捏合手指,翻页像翻书一样挥手。但不同设备、不同开发需求,需要搭配不同版本的SDK(软件开发工具包),这就像“不同型号的手机要装对应版本的APP”。

一、基础认知:先选对版本,避免开发走弯路

Rokid手势识别技术随SDK版本迭代持续优化,不同版本适配的Unity(开发工具)、设备、功能都不一样。咱们先看一张“版本适配表”,选对版本再动手:

UXR SDK 版本 支持 Unity 版本 核心功能差异 适配设备 适合人群
UXR 2.0 2020/2021/2022 LTS 基础4类手势(捏合/握拳/手掌/松开)、基础远近场切换 Station 2、Max Pro、AR Lite 新手入门、常规手势交互开发
UXR 3.0 2022/2023.3 LTS 新增图像识别(如扫二维码)、手势置信度过滤、模型轻量化30% Station Pro、Max 2、AR Studio 高级交互、性能优化需求开发者

举个例子:如果你的电脑装的是Unity 2023,就选UXR 3.0;如果用的是2021且只需要简单手势,UXR 2.0更稳定(参考Rokid版本文档)。

二、技术拆解:Rokid手势识别的“三阶段秘密”

不管是UXR 2.0还是3.0,手势识别的核心逻辑都是“看得到手→认得出手势→跟得上手”,但3.0在每个阶段都做了优化。咱们一步步拆,全程不用复杂术语。

2.1 看得到手——Rokid的“AR专属眼睛”

要让设备“看见”手,那肯定要在算法和摄像头这方面下足功夫。Rokid 的 3D 手势算法在这个领域取得了关键性突破。在手势识别方面,只依赖一颗普通的 RGB 摄像头,无需复杂的多摄像头或 ToF(飞行时间)传感器。大大降低了硬件成本,同时保持了高精度和稳定性。

  1. 利用 AI 算法和深度学习模型,Rokid的“AR专属眼睛” 能实时捕捉手部的 3D 姿态信息,包括手部的 6DoF(六自由度)位置、26 个关节点的自由度(26DoF)以及 Hand Mesh(手部网格)信息。
  2. 在响应速度上,该算法在移动端实现了毫秒级的响应速度,单帧检测耗时低于 10 毫秒,识别准确率达到 99%,且深度估计误差小于 5 厘米。
  3. 并且该算法可以运行在多种硬件架构上,包括 CPU、GPU 和 NPU,适配高通、海思等主流平台

2.2 认得出手势——给手“画骨架”再判断

设备看清楚手后,下一步是“认出你在做什么手势”,核心是“标骨骼点→看姿势”,UXR 3.0在分类精度上做了优化。

  1. 26个骨骼点:给手“标关键位置”

你把手张开,Rokid会在手上“标26个点点”,像医生画关节标记,每个点都有用:

  • 腕部(WRIST):确定手的“根在哪”,避免手移动判错位置;
  • 掌心(PALM):判断手“面朝设备还是背对设备”——掌心朝设备就是想“直接摸”;
  • 指尖(食指尖、拇指尖):判断“捏合”“点击”的关键,UXR 3.0的骨骼点定位精度提升了10%,指尖位置更准。

设备怎么找这些点?用“热力图回归”——给手画“热力图”,哪个位置亮,哪个就是骨骼点,比如食指尖是“亮斑”,直接找亮斑就行。

26个节点,分别是手腕WRIST,掌心PALM,4个掌骨(METACARPAL)节点,和5根手指关节节点,拇指从CMC指骨末节依次MCP、IP、TIP指尖,其他从MCP指骨末节依次PIP、DIP、TIP指尖。

  1. 手势分类:看“骨架姿势”下判断

有了骨骼点,设备就像“看姿势猜动作”,通过“点和点的关系”判断手势。咱们用表格总结常见手势,还标了版本优化:

手势类型 核心判断条件(大白话) 对应现实动作 版本优化(UXR3.0)
捏合(Pinch) 拇指尖+食指尖距离<2cm,其他手指弯 捏小物件(如豆子) 新增“置信度过滤”,<80%不响应,误判少30%
握拳(Grip) 所有指尖都靠近掌心 攥拳头 支持“半握拳”识别,不用完全攥紧
手掌(Palm) 所有手指伸直,指尖离掌心远 张开手要东西 手掌倾斜30°也能识别,更灵活
捏合松开(OpenPinch) 之前是捏合,现在拇指+食指距离>4cm 松开东西 响应速度快了10ms,更跟手

比如你戴戒指捏合,UXR 3.0能忽略戒指干扰,只要指尖距离够近就认“捏合”,不用“为了凑手势摘戒指”。

2.3 近/远场手势:实现 “距离一变,模式就换”

Rokid将手势分为近场手势和远场手势:直接进行触碰互动的,称为近场手势;通过射线和锚点远距离操控的,是远场手势。近场手势和远场手势的切换,是通过手与互动物体的距离判定,这个值可以根据具体使用场景调节。默认设置是,手在距离互动物体 -0.02m ~ 0.04 m 范围内,是近场手势;超出则为远场。

在 UI 操作上Rokid 通过 “近→触→压→抬” 四阶段交互反馈实现:默认时 UI 保持静止;手靠近进入 hover 状态,按钮向上抬动 “预告交互”;手指触摸时,按钮微变色、微缩放;按压到底,按钮高亮放大且触发 “Down” 音效;手抬起,按钮复原,“Up” 音效响起,完成点击。

2.4 跟得上手——快反应+低门槛

技术再厉害,手一动、虚拟东西半天才动就很糟;开发者要写几百行代码也没人用。Rokid在“跟手”和“开发门槛”上做了很多优化,3.0更突出。

  1. 快反应:手势和虚拟动作“同步”

你手一动,虚拟东西马上动,背后是两个关键优化:

  • 轻量化模型:把识别算法“压缩”——UXR 3.0的模型比2.0小30%,像大文件压成小文件,不占内存还跑得快,识别延迟从120ms降到100ms(人眼几乎感觉不到);
  • 动态帧率调节:设备“看情况干活”——手不动时识别频率降为20fps(省电量),手快速动时升为30fps(不延迟),UXR 3.0的帧率切换更平滑,不会卡顿。

  1. 低门槛:开发者不用“从零造轮子”

Rokid把复杂技术封装成“现成工具”,不同版本的SDK导入和使用略有差异,咱们分版本说:

操作步骤 UXR 2.0 实现方式 UXR 3.0 实现方式(优化后)
1. 导入SDK 从官网下载压缩包,手动拖进Unity 通过Unity Package Manager(UPM)导入,输仓库地址:https://docs.unity.cn/cn/current/Manual/Packages.html
2. 开启手势模块 拖“RKInput”预制体,勾选“Gesture” 同上,但新增“一键启用”按钮,不用找模块
3. 获取手势数据 调用GesEventInput.Instance.GetGestureType(HandType.RightHand) 同上,还能获取“手势置信度”(如GetGestureConfidence())

举个最简单的例子:开发者要实现“手势点击按钮变色”,不管2.0还是3.0,都只要3步,3.0还更简单:

  1. 拖“PointableUI”预制体到场景(2.0/3.0都有);
  2. 在预制体里加个按钮;
  3. 写几行代码(如下),3.0还能加“置信度判断”:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Rokid.UXR.Module; // 需导入命名空间

public class GestureBtn : MonoBehaviour, IPointerClickHandler
{
    private Image btnImg;
    void Start() {
        btnImg = GetComponent<Image>();
    }

    // 手势点击时触发
    public void OnPointerClick(PointerEventData eventData) {
        // UXR 3.0新增:判断手势置信度,避免误点击
        float confidence = GesEventInput.Instance.GetGestureConfidence(HandType.RightHand);
        if (confidence > 0.8f) { 
            btnImg.color = Color.green; // 置信度>80%才变色
        }
    }
}

三、实战:UXR 3.0 做“手势抓立方体”

3.1 全流程架构图(理解数据流向)

手势抓立方体的核心是「硬件采集→算法处理→SDK 分发→应用响应」,分版本数据流向差异如下(基于 Rokid AR Platform 架构简化):

3.2 前置准备:UXR 3.0 环境确认

硬件环境

为了顺利接入UXR3.0 SDK,硬件环境要求如下:

  • 可进行Unity开发的PC设备:支持用于Unity开发的Mac或Windows PC设备。
  • 空间计算设备:配备Rokid Station Pro/Rokid Station2设备。
  • 眼镜设备:配备Rokid Max Pro/Rokid Max/Rokid Max2眼镜。

软件环境

作为专为Unity开发者打造的高级开发工具包,Rokid Unity OpenXR Plugin要求开发者具备完整的Unity开发环境以及对应的Android Build Support(包括Android SDK、NDK工具链和OpenJDK)。具体版本要求如下:

  • Unity开发环境:使用Unity 2022 LTS版本。
  • Android Build Support环境:
    • Android SDK
    • NDK Tools
    • OpenJDK
  • 移动平台支持:Android Platform号码应为28至34。
  • 操作系统要求:YodaOS系统版本不低于v3.30.003-20250120-800201。

详细安装步骤这里可以参考官方文档 【一键直达】来一步步进行就好啦

3.3 步骤1:场景搭建与 UXR 3.0 专属配置

3.3.1 添加核心组件

  1. 拖入交互预制体
    1. RKHand 预制体拖入场景,展开 RKHandRightHandInteractors,保留默认的 PokeInteractor(近场抓取)和 RayInteractor(远场射线),开启 **InteractorStateChange** 脚本(默认启用,支持自动远近场切换,也可后续自定义);
    2. 选中 RightHandInteractors 下的 InteractorStateChange,在 Inspector 面板设置:
      • “Near Field Threshold”:0.8m(近场触发距离,可按需调整);
      • “Gesture Confidence Filter”:0.8(过滤置信度<80%的手势,减少误判,UXR 3.0 新增)。
  2. 创建可抓取 Cube
    1. 右键创建 3D Object → Cube,命名“GrabCube”,配置参数:
      • TransformPosition(0, 1.2, 0.8)(相机前方 0.8m,刚好触发近场)、Scale(0.2, 0.2, 0.2)
      • 挂载组件:Box Collider(取消“Is Trigger”,确保交互碰撞)、RayInteractable(Rokid 专属交互组件,允许手势识别)。
  3. 开启骨骼可视化(调试必备):选中 RKHandRightHandRender,勾选 SkeletonLine 组件,设置“Line Color”为红色,运行后可直观看到手部 26 个骨骼点(对应 SkeletonIndexFlag 枚举,如掌心 PALM、食指尖 INDEX_FINGER_TIP)。

3.4 步骤2:核心脚本开发

创建脚本 UXR3_GrabLogic,挂载到“GrabCube”上。核心逻辑:通过 GesEventInput 获取手势类型+置信度,结合骨骼点位置实现“捏合抓取→跟随→握拳释放”,融入 UXR 3.0 置信度过滤,避免误触发。

using Rokid.UXR.Module;
using UnityEngine;

public class UXR3_GrabLogic : MonoBehaviour
{
    [Header("UXR 3.0 抓取配置")]
    public HandType targetHand = HandType.RightHand; // 目标手(默认右手)
    public float followSensitivity = 0.1f; // 跟随灵敏度(值越小越平缓)
    public float minConfidence = 0.8f; // 最小手势置信度(低于则不响应)

    private bool isGrabbed = false;
    private Vector3 lastPalmPos; // 上一帧掌心位置(用于计算跟随位移)
    private MeshRenderer cubeRenderer; // 立方体渲染器(用于视觉反馈)

    void Start()
    {
        // 初始化组件引用
        cubeRenderer = GetComponent<MeshRenderer>();
        cubeRenderer.material.color = Color.white; // 默认颜色

        // 初始化掌心位置(获取掌心骨骼点,对应文档 SkeletonIndexFlag.PALM)
        if (GesEventInput.Instance.IsHandDataValid(targetHand))
        {
            lastPalmPos = GesEventInput.Instance.GetSkeletonPose(SkeletonIndexFlag.PALM, targetHand).position;
        }
    }

    void Update()
    {
        // 1. 校验手部数据有效性(UXR 3.0 新增接口,避免空引用)
        if (!GesEventInput.Instance.IsHandDataValid(targetHand))
        {
            if (isGrabbed) ReleaseCube(); // 手部丢失时自动释放
            return;
        }

        // 2. 获取当前手势类型与置信度(UXR 3.0 核心接口)
        GestureType currentGes = GesEventInput.Instance.GetGestureType(targetHand);
        float currentConf = GesEventInput.Instance.GetGestureConfidence(targetHand);

        // 3. 手势判断:置信度达标才执行逻辑
        if (currentConf < minConfidence) return;

        // 抓取:捏合手势(GestureType.Pinch)
        if (currentGes == GestureType.Pinch && !isGrabbed)
        {
            GrabCube();
        }
        // 释放:握拳手势(GestureType.Grip)
        else if (currentGes == GestureType.Grip && isGrabbed)
        {
            ReleaseCube();
        }

        // 4. 抓取状态下:跟随掌心移动
        if (isGrabbed)
        {
            FollowPalm();
            // 调试:绘制掌心到食指尖的连线(直观查看骨骼点位置)
            DrawSkeletonDebugLine();
        }
    }

    /// <summary>
    /// 抓取立方体:改变颜色+标记状态
    /// </summary>
    private void GrabCube()
    {
        isGrabbed = true;
        cubeRenderer.material.color = Color.red;
        Debug.Log($"抓取成功!手势置信度:{GesEventInput.Instance.GetGestureConfidence(targetHand):F2}");
        // 更新初始掌心位置(避免抓取瞬间位移过大)
        lastPalmPos = GesEventInput.Instance.GetSkeletonPose(SkeletonIndexFlag.PALM, targetHand).position;
    }

    /// <summary>
    /// 释放立方体:恢复颜色+重置状态
    /// </summary>
    private void ReleaseCube()
    {
        isGrabbed = false;
        cubeRenderer.material.color = Color.white;
        Debug.Log("释放立方体");
    }

    /// <summary>
    /// 跟随掌心移动:基于掌心骨骼点位置计算位移
    /// </summary>
    private void FollowPalm()
    {
        Vector3 currentPalmPos = GesEventInput.Instance.GetSkeletonPose(SkeletonIndexFlag.PALM, targetHand).position;
        // 计算位移=当前掌心位置 - 上一帧位置,乘以灵敏度
        Vector3 moveDelta = (currentPalmPos - lastPalmPos) * followSensitivity;
        // 驱动物体移动
        transform.position += moveDelta;
        // 更新上一帧位置
        lastPalmPos = currentPalmPos;
    }

    /// <summary>
    /// 调试:绘制掌心到食指尖的骨骼连线(红色)
    /// </summary>
    private void DrawSkeletonDebugLine()
    {
        Pose palmPose = GesEventInput.Instance.GetSkeletonPose(SkeletonIndexFlag.PALM, targetHand);
        Pose indexTipPose = GesEventInput.Instance.GetSkeletonPose(SkeletonIndexFlag.INDEX_FINGER_TIP, targetHand);
        Debug.DrawLine(palmPose.position, indexTipPose.position, Color.red);
    }
}

3.5 步骤3:远近场控制

方案1:保留默认自动切换(适合新手)

无需额外代码,InteractorStateChange 脚本会自动根据距离切换:

  • 手靠近 Cube(<0.8m):启用 PokeInteractor(近场抓取,Cube 变红跟随);
  • 手远离 Cube(>0.8m):启用 RayInteractor(远场射线,可点击 Cube 触发颜色变化)。

方案2:自定义强制近场(适合特定场景)

若只需近场抓取,无需远场,可通过代码禁用远场组件:

UXR3_GrabLogicStart() 中添加:

// 找到右手的 RayInteractor(远场)并禁用
var rayInteractor = GameObject.Find("RKHand/RightHandInteractors")?.GetComponent<RayInteractor>();
if (rayInteractor != null) rayInteractor.enabled = false;

3.6 步骤4:运行测试与验证

  1. 设备连接:用 Type-C 线连接 Station Pro 与电脑,Unity 中选择“Build And Run”,安装 APK 到设备;
  2. 功能验证
    1. 骨骼可视化:戴眼镜后,右手伸出,可看到红色骨骼点连线;
    2. 抓取:右手捏合(置信度>80%),Cube 变红并跟随掌心移动;
    3. 释放:右手握拳,Cube 变白并停止跟随;
    4. 远近场切换(方案1):手远离 Cube 到 1m 外,射线自动激活,点击 Cube 可触发颜色变化。

四、版本避坑指南:新手常遇问题

4.1 问题排查总流程图(先定位再解决)

4.2 高频问题明细

问题1:SDK 导入后找不到「RKInput」预制体

类别 根因分析 UXR 2.0 解决方案 UXR 3.0 解决方案
现象 1. SDK 未完全导入;2. 路径错误;3. 版本不兼容 1. 重新拖入 SDK 文件夹,确保「Import All」;
2. 手动路径:Assets/Rokid/UXR/Resources/Prefabs/Input
3. 确认 Unity 是 2020-2022 LTS
1. 重新导入 UPM 包(删除后重新添加 Git 地址);
2. 手动路径:Packages/Rokid XR/UXR/Resources/Prefabs/Input
3. 确认 OpenXR 已安装
预防措施 - 导入时关闭 Unity 其他窗口;
- 记录预制体路径到记事本

问题2:真机运行后,Cube 不跟随手部移动(无报错)

类别 根因分析 UXR 2.0 解决方案 UXR 3.0 解决方案
现象 1. 手部未进入识别区;2. 灵敏度太低;3. 事件未绑定 1. 手放在相机前方 0.3-1m,掌心朝设备;
2. 脚本中 dragSensitivity 设为 0.15;
3. 检查 EventWrapper 的事件是否绑定(WhenSelect 等)
1. 同 2.0,但识别区扩大到 0.2-1.2m;
2. dragSensitivity 设为 0.1(3.0 灵敏度默认更低);
3. 检查「Gesture Confidence Threshold」是否>0.9(过高会过滤有效手势)
调试技巧 1. UXR 2.0:在 Update 加 Debug.Log(handPos)
2. UXR 3.0:开启骨骼可视化,看掌心点是否移动

问题3:打包 APK 后,手势突然无响应(编辑器中正常)

类别 根因分析 UXR 2.0 解决方案 UXR 3.0 解决方案
现象 1. Android 权限未加;2. 系统版本过低;3. 打包配置错误 1. 在 AndroidManifest.xml 加权限:
<uses-permission android:name="android.permission.CAMERA"/>
2. 设备系统升级到 ≥ v1.8.0;
3. 确认「Target API Level」是 31
1. 同 2.0,额外加 OpenXR 权限:
<uses-feature android:name="android.hardware.vr.high_performance"/>
2. 设备系统升级到 ≥ v2.0.0;
3. 打包时选择「Build App Bundle (Google Play)」
验证方法 安装 APK 后,在「设置→应用→权限」中确认「相机」已开启

问题4:UXR 3.0 中骨骼点不显示(SkeletonLine 已勾选)

类别 根因分析 解决方案(仅 UXR 3.0)
现象 1. HandRender 组件未启用;2. 骨骼点数据未获取;3. 颜色与背景一致 1. 找到 RKHand → RightHandRender,确认 HandRender 组件「Enabled」勾选;
2. 在脚本中加 Debug.Log(GesEventInput.Instance.IsHandDataValid(HandType.RightHand)),确认返回 true
3. 调整 SkeletonLine 的「Line Color」为红色(默认白色可能与背景融合)
预防措施 初始化时调用 ToggleSkeletonVisual(true) 脚本方法

4.3 开发者论坛提问

如果以上方案都没有解决你的问题,你还可以前往 Rokid 官方论坛发帖提问,邀请论坛里的各路技术大神共同探讨,助力问题解决。

  • 访问https://forum.rokid.com/index;
  • 选择「技术求助」分类,标题格式:「【UXR X.0】+ 问题现象」(如「【UXR 3.0】Cube 不跟随手部」);
  • 内容需包含:Unity 版本、SDK 版本、设备型号、报错日志(从 Android Studio Logcat 导出)。

五、总结

拆解完技术后,你是不是发现 Rokid 手势识别的 “核心秘密” 其实很简单?Rokid 早已将复杂的底层技术 “化繁为简”,而剩下的无限可能,就全靠你的创意去延伸 —— 比如用手势轻松操控虚拟台灯,或是通过手势趣味玩转 AR 积木,让 AR 真正融入你的日常生活。现在就用 Rokid,去开发属于你的创意项目吧!

附录

除此之外,我还为大家整理梳理了核心资源合集,涵盖部署配置规范、开发工具包等关键内容,希望能为各位的 Rokid 开发工作提供帮助。

资源名称 链接 资源介绍
UXR3.0开发工具包 【一键直达】 XR3.0 SDK是Rokid为Unity开发者提供的AR开发工具包,提供空间定位跟踪、双目渲染、手势交互等能力;UXR3.0 SDK的运行平台为Rokid AR Studio/AR Lite 。支持 Unity2022 LTS 版本。
Rokid若琪学院 【一键直达】 官方学习资源,包括XR知识讲解,Rokid设备知识、空间多模态交互使用手势交互、射线、语音等。
YodaOS-Master 系统说明书 【一键直达】 YodaOS-Master是一套以空间交互为核心的AR空间计算操作系统。包括空间定位、空间交互、空间音频、空间渲染和空间显示等能力。
SDK下载 【一键直达】 Rokid 全系列设备软件开发工具包(SDK)汇总
RoKid开发者论坛 【一键直达】 连接开发者与官方的核心支持与交流平台
开发者常见FAQ 【一键直达】 Rokid 开发者常见 FAQ 集合,整合开发全流程高频疑问的官方标准化解答。
Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐