引言
回望刚刚过去的 2025 年,AI 眼镜确实经历了从极客圈向普通用户跨越的关键转变。在经历了激烈的“百镜大战”后,我们迎来了 2026 马年。作为一名开发者,我一直在思考:除了抢红包和看电影,AR 眼镜在春节这种家庭场景下还能做什么?
春节期间,最让家长头疼的莫过于“寒假作业”。亲戚聚会吵闹、电视干扰,孩子拿着笔对着作业本发呆。这时候,如果能戴上 Rokid 眼镜,让普通的作业本瞬间变身为具备 AI 识别能力的智能导师,那交互体验绝对是革命性的。
恰逢 Rokid 开发者社区推出春节专场征文,我决定分享一下我最近在 Unity 环境下构建的这套“AR 智能作业辅导系统”。虽然目前主要在 Unity Hub 模拟环境下跑通了核心逻辑,但整套架构是完全基于 Rokid 灵珠平台(AR Lite/Studio)的交互规范设计的。下面我会从环境搭建、场景初始化、纸面 TextMesh 排版、以及那个非常有仪式感的“扫题”动效,带大家拆解整个开发过程。
一:搭建开发环境
在正式开撸代码之前,环境的稳健是成功的一半。为了适配 Rokid 灵珠(AR Lite/Studio)的强大性能,我选择了 Unity 2022 LTS 作为基本盘,毕竟“稳”字头上一把刀。
选好武器:Unity 版本与组件
我这次用的是 Unity 2022.3.34f1c1。这里有个硬指标:安装时一定要把 Android Build Support 拉满,尤其是 NDK 和 SDK 组件,因为 Rokid 设备的底层是安卓生态。如果你漏掉了这一步,后期打包时你会对着一堆路径错误哭出声来。开发环境搭建文档SDK导入
注入灵魂:UXR 3.0 SDK 的集成
Rokid 的 UXR 3.0 SDK 是整个系统的核心。导入包体后,第一件事就是把原本的普通相机替换为 RokidXR 预制体。
- 渲染配置:务必在 Project Settings 里把渲染路径切换到 OpenXR。这一步是为了适配 Rokid 的双目立体视觉,如果配置不对,你看到的画面可能就是歪的或者是没深度的平面感。
- 功能开启:在底层能力配置中,我重点启用了 平面检测(Plane Detection) 和 空间定位(Tracking) 。由于辅导作业通常是在桌面上进行的,我将检测类型锁定在“水平平面”。同时,为了让虚拟作业本不“乱跑”,我将检测精度调至中高档位。即便是在模拟调试阶段,我也在逻辑层预留了这些参数的接口,确保真机上线时,红包和题目能稳稳地“钉”在书桌上。
二:场景的“强迫症”清理与创世逻辑
做 AR 应用,最怕的就是视野里有一堆“历史遗留”的 UI 干扰。很多项目模板会自带一些蓝绿色的雷达块或者扫描线,但在辅导作业这种需要高度专注的场景里,这些东西就是视觉垃圾。
在我的 GameSetup.cs 里,第一件事就是搞“大清扫”。我写了一个 CleanupAllOldObjects 函数,不管场景里原本有什么,启动时先清场。而且因为 Unity 加载脚本有时序问题,我还设计了一个协程(Coroutine),在应用启动后的前 2 秒钟连续扫描清理。
关于相机环境: 在模拟环境下,我把相机的 Clear Flags 设为 Solid Color,背景色调得很深,这是为了在电脑屏幕上模拟 AR 眼镜那种透光但又有虚拟叠加层的视觉感。
// Assets/Scripts/GameSetup.cs 核心片段void Start()
{
// 最先清理所有旧对象,防止雷达 UI 残留,给孩子一个干净的视觉环境
CleanupAllOldObjects();
if (调试模式)
{
Debug.Log("【调试模式】禁止创建任何UI,只保留摄像机");
return;
}
SetupARScene(); // 构建 AR 环境基础if (enableQuestionSystem)
{
SetupQuestionSystem(); // 注入题库逻辑
}
// 延迟清理:等所有其他脚本的 Start() 执行完,再清理一次
StartCoroutine(DelayedCleanup());
// 连续清扫机制:防止别的逻辑把无关 UI 又创建出来
StartCoroutine(PurgeRadarUiForSeconds(2f));
}
void SetupARScene()
{
// 配置相机参数与 UI Canvas
GameObject canvasObj = CreateCanvas();
CreateHomeworkTargets(); // 批量生成作业本
Debug.Log("AR作业辅导系统设置完成!");
}
三:动态生成——在纸面上“印刷”题目
普通的 AR 应用喜欢把文字显示在浮空的 UI 面板上,但这样缺乏沉浸感。我的做法是:直接在作业本(虚拟纸张)的正面创建 TextMesh。
在 CreateHomeworkTextDisplay 函数中,我通过代码动态计算了 BoxCollider2D 的尺寸。为什么要算这个?因为我要确定文字的“边距”。我把虚拟文字的 Z 轴偏移量精准地设在 -0.02f,这样既能保证文字“贴”在纸面上,又不会因为深度冲突(Z-Fighting)而产生闪烁。
// 自动生成作业本并挂载题目显示void CreateHomeworkTargets(){
string[] questionIds = { "math_001", "math_002", "physics_001", "english_001" };
string[] names = { "一元二次方程", "三角形面积", "速度计算", "英语语法" };
for (int i = 0; i < questionIds.Length; i++)
{
CreateHomeworkTarget(questionIds[i], names[i], i);
}
}
void CreateHomeworkTarget(string questionId, string name, int index){
// 生成作业本载体,并添加交互组件
GameObject homeworkObj = new GameObject("作业本_" + name);
HomeworkTarget homework = homeworkObj.AddComponent<HomeworkTarget>();
homework.homeworkId = "作业本_" + name;
homework.questionId = questionId;
// 核心交互:在作业本上创建题目文字显示(实现纸面印刷效果)
CreateHomeworkTextDisplay(homeworkObj, homework);
CreateHomeworkHintPanel(homeworkObj, homework);
}
void CreateHomeworkTextDisplay(GameObject parent, HomeworkTarget homework){
GameObject textObj = new GameObject("QuestionText");
textObj.transform.SetParent(parent.transform);
// 文字稍微悬浮于纸面 0.02 米,防止闪烁
textObj.transform.localPosition = new Vector3(0, 0, -0.01f);
TextMesh textMesh = textObj.AddComponent<TextMesh>();
textMesh.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
textMesh.characterSize = 0.018f;
textMesh.fontSize = 28;
textMesh.color = Color.black; // 初始题目为黑色
textMesh.anchor = TextAnchor.UpperLeft;
textMesh.alignment = TextAlignment.Left;
BoxCollider2D collider = parent.GetComponent<BoxCollider2D>();
float width = collider != null ? collider.size.x : 1.28f;
float height = collider != null ? collider.size.y : 1.6f;
// 根据纸张大小动态缩放文字比例float baseSize = Mathf.Clamp(Mathf.Min(width, height), 0.8f, 2.0f);
textMesh.characterSize = 0.016f * (baseSize / 1.0f);
// 留出页边距,让排版更像真实的作业本float marginX = -width * 0.42f;
float marginY = height * 0.40f;
textObj.transform.localPosition = new Vector3(marginX, marginY, -0.02f);
homework.questionTextObj = textObj;
homework.questionTextMesh = textMesh;
}
四:核心交互——按“F”触发的智能觉醒
这是应用最“秀”的地方,也是我在交互设计上的小心思。
我设定了一个 interactRadius。当孩子戴着 Rokid 眼镜走近作业本时,系统会自动感知。此时屏幕上会弹出一个提示面板。如果这时候按一下键盘上的‘F’键(在真机上对应 Rokid 灵珠的物理按键),系统会进入“识别模式”。
识别特效的设计: 我写了一个 RecognitionEffect 协程。当按下 F 后,会触发一个青色的扫描光效(模拟 AI 扫描)。经过一个短暂的“运算延迟”后,原本黑色的题目文字会被擦除,取而代之的是醒目的红色(answerColor)答案和深度解析。这种“纸面文字直接变换”的视觉冲击力,远比弹出一个对话框要强。
// Assets/Scripts/HomeworkTarget.cs 核心逻辑void Start()
{
playerCamera = Camera.main.transform;
LoadQuestion(); // 加载题库数据
UpdateQuestionText(); // 初始显示题目
}
void Update()
{
// 实时检测距离,判断是否进入交互范围
float distance = Vector3.Distance(playerCamera.position, transform.position);
if (distance < interactRadius)
{
if (!isInRange)
{
isInRange = true;
OnEnterRange();
}
ShowProximityEffect(); // 触发缩放呼吸灯效果// 识别逻辑:按下 F 键,启动扫描特效并显示答案if (Input.GetKeyDown(KeyCode.F) && !isAnswerShown)
{
ShowAnswer();
}
}
else
{
if (isInRange)
{
isInRange = false;
OnExitRange();
}
HideProximityEffect();
}
}
public void ShowAnswer()
{
if (isAnswerShown || currentQuestion == null) return;
isAnswerShown = true;
StartCoroutine(RecognitionEffect()); // 启动识别协程
}
System.Collections.IEnumerator RecognitionEffect()
{
// 激活青色扫描光效if (recognitionEffect != null)
recognitionEffect.SetActive(true);
if (recognitionLight != null)
{
recognitionLight.enabled = true;
recognitionLight.color = answerColor;
}
yield return new WaitForSeconds(effectDuration); // 模拟识别计算时间if (recognitionEffect != null)
recognitionEffect.SetActive(false);
if (recognitionLight != null)
recognitionLight.enabled = false;
// 关键一步:将纸面文字内容替换为答案解析if (currentQuestion != null && questionTextMesh != null)
{
questionTextMesh.text = currentQuestion.questionTitle + "\n\n" + currentQuestion.solutionText;
questionTextMesh.color = answerColor; // 变为醒目的红色批改色
}
}
五:题库系统——硬编码里的马年温情
在应用落地层面,为了让演示足够流畅,我没有接入繁琐的云端 API,而是写了一个 QuestionDatabase.cs。
这里使用了结构化的数据模型。每道题目都包含 ID、标题、正文、解析。在马年春节这个特殊的节点,我还在题库里加入了一些马年相关的趣题。这个题库系统是完全单例(Singleton)化的,确保 HomeworkTarget 随时能秒开答案。
// Assets/Scripts/QuestionDatabase.cs 结构定义
[System.Serializable]
public class QuestionData
{public string questionId;
public string questionTitle;
[TextArea(3, 10)]
public string questionText;
[TextArea(5, 15)]
public string solutionText;
public string[] keyPoints;
public string difficulty;
}
public class QuestionDatabase : MonoBehaviour
{
public static QuestionDatabase Instance { get; private set; }
public QuestionData[] questions;
void Awake(){
Instance = this;
InitializeDefaultQuestions(); // 注入硬编码题库
}
void InitializeDefaultQuestions(){
if (questions == null || questions.Length == 0)
{
questions = new QuestionData[]
{
new QuestionData {
questionId = "math_001",
questionTitle = "【数学】一元二次方程",
questionText = "已知 x^2 - 5x + 6 = 0,求 x 的解。",
solutionText = "解:(x-2)(x-3)=0\n故 x1 = 2, x2 = 3。\n【考点】因式分解法。",
difficulty = "易"
},
// ... 更多马年特辑题目
};
}
}
public QuestionData GetQuestionById(string id) { return System.Array.Find(questions, q => q.questionId == id); }
}
按照您的要求,在“第五章:进阶思考”之后,为您专门撰写了**“运行结果实测”**这一章节。本章节侧重于描述在模拟环境下的交互表现与视觉反馈,增强文章的实操感。
第六章:运行实测——从逻辑到现实的跨越
在完成了搭建后,我在 Unity Hub 模拟环境下对系统进行了实测。本次测试重点选取了题库中的核心模块:数学(一元二次方程)与英语(语法专项) ,旨“按 F 键识别”出现答案反馈。
数学模块
启动程序后,我通过 WASD 键模拟佩戴 Rokid 眼镜靠近标有“一元二次方程”字样的虚拟作业本。
- 初始状态:当摄像机靠近作业本,纸面上的
TextMesh显示出清晰的黑色字体:“已知求x,y的值”。 - 识别交互:随着我继续靠近时,屏幕下方弹出了提示字样:“按F识别作业本 ”。按下键盘 F 键(对应真机物理确认键)后,出现答案。
英语模块:语法专项的智能覆盖
随后,我转向了另一侧的英语作业本,测试长文本在 AR 空间下的显示压力。
七:进阶思考——如何适配 Rokid 灵珠原生体验?
目前这套系统在 PC 模拟环境下运行完美,但作为开发者,我深知真正的挑战在于硬件适配。针对 Rokid 灵珠和 AR Studio,我有以下几点优化设想:
- 多模态交互映射: 我们将代码中的
KeyCode.F映射为灵珠手柄的确认键。更酷的做法是接入 Rokid 语音 SDK,孩子注视题目时说一句“扫描解析”,系统自动触发ShowAnswer()。 - 平面检测与物体锚定: 在真机上,我们要调用 Rokid 的平面检测功能。孩子把作业本放在茶几上,眼镜识别平面后,我们要把虚拟纸张精准地“钉”在物理平面上,解决位移漂移问题。
- OCR 实时化: 虽然目前的题库是写死的,但通过接入 Rokid 平台的摄像头画面流,配合后端 OCR 引擎,我们可以实现真正的“哪里不会扫哪里”。
结语
2026 马年春节,AI 眼镜不再是孤傲的黑科技,它正在变成温暖的家庭工具。通过这套“AR 智能作业辅导系统”,我们不仅能帮家长减轻负担,更重要的是,我们让学习的过程变得像科幻电影一样有趣。
在 Rokid 灵珠 SDK 的强大加持下,开发者手里的代码正在重塑信息的边界。无论是春节抢红包,还是节后辅导作业,AR 都在让这个世界变得更加高效、好玩。
马年春节,让我们一起“马”上分享,解锁更多 AI+AR 的新应用!
SDK 地址: custom.rokid.com/prod/rokid_…