轻松打造Unity小游戏AR体验
目录
AR会话初始化
平面追踪与相机定位
用户交互处理
实时渲染
Unity 小游戏宿主现已支持 AR 功能,本文介绍如何从零开始创建一个可以在Unity小游戏宿主上运行的AR小游戏,欢迎大家试用!
想为你的小游戏注入虚实交融的魔力吗?现在,Unity 小游戏宿主正式支持 AR 功能,助你轻松打造沉浸式增强现实体验!
🌟 为什么选择Unity小游戏宿主?
-
无缝接入:专为小游戏优化的 AR API,快速集成,省时省力
-
强大性能:基于成熟技术栈,流畅运行复杂 AR 场景
-
跨平台兼容:一次开发,多端部署,触达亿万玩家
🎮 开发者福音 无论你是想开发:
-
虚实结合的冒险游戏
-
场景互动的营销应用
-
社交 AR 小游戏 这份文档将手把手教你如何通过 Unity 宿主 AR API,快速实现AR功能!
📢 现在就开始,让你的小游戏从屏幕里"跳"出来!
AR API设计原则
本AR API基于微信VisionKit API规范开发,为Unity小游戏开发者提供与微信平台高度兼容的AR功能支持。我们采用与VisionKit一致的API命名规范,核心功能接口(如平面检测、图像追踪等)保持对齐,并支持微信VisionKit的主要数据结构格式。但需要注意,部分API的输出与原生VisionKit可能存在细微差异。
开发者可通过tj.createVKSession(option: SessionOption)函数启动基础AR功能。返回的VKSession对象可用于运动跟踪,或获取AR引擎对图片、3D物体及平面的识别结果。基于这些识别结果,开发者可实现多种AR应用场景,包括:
- 图片增强效果
- 3D物体特效展示(如在商品周围呈现广告)
- 平面虚拟物品陈列等
接下来,我们将从零开始构建一个AR小游戏。
创建AR小游戏步骤
- 定义工具类
首先创建两个核心工具类:
- ARCameraTexRenderer:负责相机背景渲染
- ARSceneRenderer:处理AR内容叠加
基础类结构如下:
class ARCameraTexRenderer {setup() {// ...// 定义着色器程序,初始化WebGL,适配屏幕比例等}render(frame) {// ...// 将相机捕获的YUV帧数据通过WebGL渲染到屏幕上}
}class ARSceneRenderer {setup() {// ...// 初始化WebGL渲染器,设置主相机,创建场景并添加光照,创建目标指示器,加载模型}render(frame) {// ...// 根据AR相机更新相机矩阵并渲染场景}
}
受限于篇幅两个工具类的实现不具体展开,如果感兴趣的话可以联系我们索取demo工程。
2.准备工作
接下来让我们做一些准备工作,通过tj.createCanvas()方法创建Canvas,并且实例化两个工具类,为简化渲染部分代码我们引入了Three.js依赖用于3D渲染。
this.canvas = tj.createCanvas();
this.THREE = createScopedThreejs(canvas);
this.glContext = this.canvas.getContext("webgl");
this.arSceneRenderer = new ARSceneRenderer(this.canvas, this.THREE);
this.arSceneRenderer.setup();
this.camTexRenderer = new ARCameraTexRenderer(this.glContext);
this.camTexRenderer.setup();
3.创建session用于平面检测 通过调用tj.createVKSession方法创建AR session。
this.session = tj.createVKSession({track:{plane:true,},version:'v1',gl:this.glContext
});
我们通过上述代码实现了支持平面检测的AR会话。通过设置不同的sessionOption参数,可以扩展更多AR功能。
关于sessionOption的配置说明:
当前基础版VKSession支持以下三种AR功能:
- 标记检测(支持图片和模型识别)
- 平面检测
- 运动跟踪
创建VKSession时,系统会根据配置参数生成相应的AR功能实例。需要注意以下事项:
- 当前版本暂不支持多跟踪功能同时启用
- 当TrackOption中配置多个功能时,系统将按照优先级顺序启用最高级别的功能:
- 运动跟踪(最高优先级)
- 平面检测
- 标记检测(最低优先级)
SessionOption参数定义如下:
interface SessionOption{// 为了兼容微信的VisionKit,保留version属性,但没有任何功能上的影响。// 可传入'v1'和'v2'。version:string// 具体的配置属性,必须传入。track:TrackOption,// webgl context。必要gl:WebGLRenderingContext
}
// 默认session只提供通用的AR功能,SSM和DSM请使用createSSMSession和createDSMSession创建
// 对应的session。同一时间只能开启一个AR功能。
interface TrackOption {// 图片/模型跟踪功能。开启之后,同时支持图片和模型的跟踪。图片支持同时跟踪多个图片。// 模型支持同时跟踪一个物体。测试工程:ARMain_Object.jsmarker:MarkersOption,// 是否开启SurfaceTrack功能。SurfaceTrack能识别平面上最近的anchor点。plane: Bool,// 开启后创建6Dof的简单运动跟踪,适合简单的AR程序。较为轻量。同时,只有在这个模式下// camera.viewMaterix才会有值,其他模式下,viewMatrix都为单位矩阵motion: Bool,
}
4.启动会话
最后,通过调用session.start()
方法即可启动AR会话。以下代码示例展示了核心功能实现,非关键代码已做简化处理。
AR会话初始化
调用session.start()
启动AR功能,开启平面检测(plane detection)功能。
平面追踪与相机定位
addAnchors
:当检测到平面时,设置标记(planeExist = true
)updateAnchors
:实时更新相机位置(通过anchor.transform
参数)
用户交互处理
当用户点击屏幕时,通过射线检测(Raycaster)在已检测的平面上放置3D模型。
实时渲染
每帧获取AR相机数据(getVKFrame
),同时渲染相机背景和3D场景。
let mainCamera = this.arSceneRenderer.mainCamera;
this.session.start(status => {// 判断status进行错误处理 ...session.on('addAnchors',anchors=>{if(anchors && anchors.length > 0){// 标记检测到平面planeExist = true;}});session.on('updateAnchors',anchors=>{if(anchors && anchors.length>0){let anchor = anchors[0];// 更新相机mainCamera.matrixWorldInverse.fromArray(anchor.transform); mainCamera.matrixWorld.getInverse(mainCamera.matrixWorldInverse);}});let raycaster = new THREE.Raycaster();tj.onTouchStart(function(evt){if(!planeExist){return;} // 未检测到平面则忽略// 计算点击位置(归一化坐标)let pointer = new THREE.Vector2()pointer.x = evt.touches[0].pageX / canvas.width * 2 - 1;pointer.y = - evt.touches[0].pageY / canvas.height * 2 + 1;// 射线检测raycaster.setFromCamera(pointer,mainCamera);const intersects = raycaster.intersectObjects( arSceneRenderer.scene.children );for(let i of intersects){if(i.object == arSceneRenderer.planeMesh){// 放置目标指示器arSceneRenderer.aimCenter.position.set(i.point.x,i.point.y,i.point.z);// 放置模型if(arSceneRenderer.currentModel){if(arSceneRenderer.putModel){return;}let obj = arSceneRenderer.currentModel;obj.scale.setScalar(0.1);obj.position.set(i.point.x,i.point.y,i.point.z);arSceneRenderer.scene.add(obj);arSceneRenderer.putModel = true;// 模型控制器 ...}}} })const onUpdate = function(){// 渲染相机背景和3D场景const frame = session.getVKFrame(canvas.width,canvas.height);if(frame && frame.camera){if(camTexRenderer.render(frame)){arSceneRenderer.render(frame); }} session.requestAnimationFrame(onUpdate);}// 启动渲染session.requestAnimationFrame(onUpdate);
});
5.运行
游戏编码已完成,现在可以在宿主设备上运行测试。启动游戏后,请按照以下步骤操作:
- 移动手机直至系统成功识别平面,屏幕上将显示平面坐标轴
- 点击屏幕即可在识别到的平面位置放置3D模型
- 移动摄像头时,模型会固定在已识别的平面位置
- 通过触屏手势可调整模型的大小和旋转角度
具体效果如下图所示: