一、 项目背景与概述
步入 2026 马年,AI 眼镜已经完成了从“显示增强”到“感知智能”的跨越。在刚过去的春节长假中,面对琳琅满目的年夜饭,“每逢佳节胖三斤”成了许多人的焦虑。作为开发者,我们如何利用 Rokid 灵珠(AR Lite/Studio) 的空间计算能力来解决这个痛点?
本项目——AR 智能卡路里计算器,通过 UXR 3.0 SDK 的空间交互框架,构建一套沉浸式的食物热量识别系统。用户无需低头查看手机,只需佩戴 AR 眼镜注视食物,系统即可通过“识别波纹”反馈并弹出精确的热量数据。
1.1 核心设计理念
- 空间生产力:将繁琐的热量查询转化为“空间即看即得”的交互。
- 零资源依赖:全程序化 3D 建模(Procedural Modeling),不依赖外部美术资源,实现秒开加载。
- 多模态前瞻:架构完美适配从鼠标模拟到 Rokid 手柄触摸、手势捏合的平滑迁移。
二、 开发环境与技术栈
本应用采用 Unity Hub 进行工程管理,底层逻辑完全遵循 Rokid XR 开发规范。
- 引擎版本:Unity 2022.3.x LTS(推荐 URP 渲染管线以获得更佳的 AR 透明度表现)。
- SDK 版本:Rokid UXR 3.0 SDK。
- 交互模式:双模式切换(水果/常用食物),FPS 第一人称观察模拟。
- 核心特性:运行时 UI 生成、程序化几何体拼装、距离感知逻辑。
开发环境搭建可以参考官方文档
三、 系统架构实现
应用采用了典型的“单例主控+模块化业务”架构。这种架构的好处在于,当我们需要从 Unity Hub 的鼠标控制迁移到 Rokid 的 6DoF 追踪时,只需要更换 CameraController 的输入源。
3.1 场景启动入口:AppLauncher
为了确保应用启动时的组件加载顺序,我们通过一个极简的种子脚本 AppLauncher 来动态激活主应用。
using UnityEngine; /// <summary>/// 脚本职责:场景启动入口/// 在 Awake 中动态挂载 ARCalorieApp,确保场景中核心管理器的唯一性与初始化时序。/// </summary>public class AppLauncher : MonoBehaviour { void Awake(){ if (GetComponent<ARCalorieApp>() == null) { gameObject.AddComponent<ARCalorieApp>(); Debug.Log(">>> AR Calorie App: 核心逻辑已通过 AppLauncher 注入并启动"); } } }
3.2 数据底座:FoodDatabase 的结构化思维
AR 应用的响应速度取决于数据的组织方式。我们定义了 FoodData 结构,并硬编码了涵盖年夜饭常见水果及高热量甜点的静态数据库。
using UnityEngine; using System.Collections.Generic; [System.Serializable] public class FoodData { public string foodName; public float calories; public string category; public FoodData(string name, float calories, string category){ this.foodName = name; this.calories = calories; this.category = category; } } public static class FoodDatabase {public static List<FoodData> allFoods = new List<FoodData> { new FoodData("苹果", 52, "水果"), new FoodData("香蕉", 89, "水果"), new FoodData("橙子", 47, "水果"), new FoodData("汉堡", 295, "快餐"), new FoodData("披萨", 266, "快餐"), new FoodData("炸鸡", 260, "快餐"), new FoodData("甜甜圈", 452, "甜点"), new FoodData("巧克力", 546, "甜点") }; public static List<FoodData> GetFruits() => allFoods.FindAll(f => f.category == "水果"); public static List<FoodData> GetFoods() => allFoods.FindAll(f => f.category != "水果"); }
3.3 空间导航:模拟环绕相机逻辑
由于在 Unity Hub 开发阶段没有真机实时追踪,我们编写了 CameraController。它模拟了用户佩戴 Rokid 眼镜时,围绕桌面食物进行“全方位视觉检阅”的体验。
using UnityEngine; // 脚本职责:模拟环绕观察相机 // 支持右键旋转(头转模拟)、WASD 平移(走位模拟)以及滚轮缩放。 public class CameraController : MonoBehaviour { public Transform target; // 观察中心点public float distance = 5.0f, minDistance = 1.5f, maxDistance = 10f; public float rotationSpeed = 120.0f; private float rotationX = 20f, rotationY = 45f; void LateUpdate(){ if (target == null) return; // 右键模拟 AR 视角转动if (Input.GetMouseButton(1)) { rotationY += Input.GetAxis("Mouse X") * rotationSpeed * Time.deltaTime; rotationX -= Input.GetAxis("Mouse Y") * rotationSpeed * Time.deltaTime; rotationX = Mathf.Clamp(rotationX, -10f, 85f); } // 缩放模拟靠近/远离物体的观察感 distance -= Input.GetAxis("Mouse ScrollWheel") * 5; distance = Mathf.Clamp(distance, minDistance, maxDistance); Quaternion rotation = Quaternion.Euler(rotationX, rotationY, 0); transform.position = target.position - (rotation * Vector3.forward * distance); transform.LookAt(target.position); } }
四、 核心业务逻辑:场景搭建与交互系统
本系统的精髓在于 ARCalorieApp 与 ARCalorieManager 的协同。前者负责“创世”(动态搭建 UI 与相机),后者负责“生命”(处理识别逻辑与模型拼装)。
4.1 主应用入口:ARCalorieApp
该模块在运行时动态创建 Canvas 和文本组件。这种做法避免了繁琐的 Prefab 引用,使得项目在不同版本的 Rokid SDK 间迁移时具有极强的空间感。
// 此处展示核心 SetupUI 逻辑片段 void SetupUI() { GameObject canvasObj = new GameObject("AR_UI_Canvas"); Canvas canvas = canvasObj.AddComponent<Canvas>(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; canvasObj.AddComponent<CanvasScaler>().uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; // 创建顶部的“识别状态”面板 GameObject infoPanel = new GameObject("InfoPanel"); infoPanel.transform.SetParent(canvasObj.transform); infoText = infoPanel.AddComponent<Text>(); infoText.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); infoText.fontSize = 40; infoText.alignment = TextAnchor.UpperCenter; // ... UI 布局代码省略 ... }
4.2 业务核心:ARCalorieManager 的“空间识别”
这是系统最复杂的部分。它处理三件事:
- 多模式切换:通过 Z 键在“水果”和“正餐”模式间切换。
- 程序化建模:利用 Unity 几何体实时拼装 3D 物体。
- 识别动效:通过协程实现“识别中...”的文字跳动动画,并根据热量高低显示不同颜色的预警标签。
// 此处展示卡路里预警颜色逻辑 private void RecognizeCalories() { if (isScanning) return; StartCoroutine(ScanningRoutine()); } IEnumerator ScanningRoutine() { isScanning = true; float timer = 0f; while (timer < 1.5f) { // 模拟 AI 运算文字动效string dots = new string('.', (int)(Time.time * 5) % 4); UpdateUIText($"AI 深度识别中{dots}"); timer += Time.deltaTime; yield return null; } // 根据数据计算卡路里颜色等级 Color calorieColor = GetCalorieColor(currentFood.calories); DisplayCalorie(currentFood.calories, calorieColor); isScanning = false; } Color GetCalorieColor(float kcal) { if (kcal < 60) return Color.green; // 低热量if (kcal < 200) return Color.yellow; // 中热量if (kcal < 400) return Color.orange; // 高热量return Color.red; // 热量炸弹 }
五、 技术细节探讨:程序化几何体建模
在 Rokid 灵珠这种追求轻量化的 AR 设备上,减少纹理内存(Texture Memory)占用至关重要。本项目采用了 运行时几何体拼装技术。
5.1 苹果(Apple)的拼装逻辑
我们并不使用 FBX 模型,而是使用 GameObject.CreatePrimitive(PrimitiveType.Sphere) 创建果体,再通过 Cylinder 缩放作为果蒂。这种方式不仅加载速度极快,且在 AR 空间中具有非常清晰的边缘(Aliasing),非常适合用于科普和教学演示。
5.2 甜甜圈(Donut)的拼装算法
甜甜圈的实现通过 12 个微型 Cylinder 进行环形排列,并赋予高度光滑的 Standard Shader 材质。这种“乐高”式的建模思想,能让开发者在没有美术支持的情况下,快速构建出一个包含数十种食物的 3D 库。
六、 适配 Rokid 灵珠的多模态交互方案
虽然目前应用运行在 Unity Hub 的键鼠模拟环境下,但架构已经为 Rokid SDK 预留了接口:
- 从键盘到触摸板(Rokid AR Lite): 我们将代码中的
Input.GetKeyDown(KeyCode.F)直接映射为灵珠手柄的触摸板点击事件。模式切换(Z 键)则映射为侧边返回键或滑动交互。 - 从模拟到空间(Rokid AR Studio): 利用 UXR 3.0 的手势识别能力,我们可以将“确认识别”定义为手势的“捏合(Pinch)”。当用户注视食物并捏合手指时,代码中的
RecognizeCalories()被触发,这种无接触交互将极大地提升春节餐桌上的使用体验。
七、 运行体验与效果实测
在 Unity Hub 的模拟环境下,“水果模式”与“常用食物模式”进行了测试。虽然目前的运行是 PC 环境,但通过 CameraController 和深色背景模拟,应用展现出了空间交互感。
点击运行,效果运行加载,我们z键进行食物、水果切换,f键识别卡路里,键盘上下左右切换。
八、 结语:AR 赋能健康生活
马年春节,科技不仅是点缀,更是守护。通过这套 AR 智能卡路里识别系统,我们不仅展示了 Unity 引擎在空间计算领域的灵活性,更体现了 Rokid 灵珠平台在生活化场景下的巨大潜力。
从一行行代码到空间中跳动的热量数值,我们正在定义一种全新的认知世界的方式。希望每一位 Rokid 开发者都能在这个春天,“马”不停蹄,解锁更多 AI+AR 的无限可能。