大咖介绍
AR是增强现实(AugmentedReality)的缩写,是一种将虚拟信息与真实世界巧妙融合的技术。首先通过摄像头捕获到真实世界的影像,辅以陀螺仪等传感器数据信息,通过软件算法为真实世界的影像构建虚拟空间的三维坐标系,在这个坐标系基础上添加三维模型等,从而达到使用虚拟信息与真实世界影像融合呈现的效果。
AR的优势
1.一套完成的VR(虚拟现实)设备价格不菲,而AR主流手机均可以支持。
2.得益于智能手机的普及,AR的受众人群更广泛。
3.AR应用场景广泛,包括:教育、医疗、购物、娱乐、传媒、旅游、军事等。
主流AR SDK对比
SDK
特点
平台
苹果ARKit
平面检测、运动跟踪、光线评估
iOS11,A9及以上处理器(iPhone6s及以后设备)
谷歌ARCore
平面检测、运动跟踪、光线评估
国内支持设备较少,并且需要安装Google Play和ARCore套件
Easy AR SDK
目前缺少平面检测和光线评估
Unity AR Foundation
底层技术基于ARKit和ARCore封装,对Unity开发非常友好
同ARKit和ARCore的设备
苹果的发布ARKit,提出的平面检测、运动跟踪、光线评估三大特色功能,把AR技术应用刷新到一个新的高度;谷歌紧随其后,发布了具有同样特色功能的ARCore。在需要平面检测,面积计算这样的AR应用场景,国内老牌的EasyAR已不能满足需求。Unity为了更好的支持游戏开发中应用AR技术,抽象了UnityAR Foundation框架,实现“构建一次,多平台部署”。无疑UnityAR Foundation已成为Unity中开发AR应用的首选框架。
Unity AR Foundation 架构
UnityAR Foundation需要Unity2019以上版本。ARFoundation 通过XR插件来支持不同的平台,不同平台对应的XR插件如下:
*Android 上需要ARCoreXR Plugin
*iOS 需要ARKitXR Plugin
*Magic Leap 需要MagicLeap XR Plugin
*HoloLens 需要WindowsXR Plugin
ARFoundation的框架图如下:
AR应用基于ARFoundation开发,ARFoundation屏蔽了不同平台ARSDK的API差异。
架构搭建AR Foundation项目
首先创建一个空的3D项目,然后点击菜单Window=> Package Manager, 在弹出的PackageManager窗口中搜索AR,在列表中选择ARKitXR Plugin进行安装。要使用ARFoundation,必须安装一个XRPlugin,考虑到iOS调试的便利性,我们选择iOS平台的ARKitXR Plugin进行初次学习。
ARKitXR Plugin的安装会自动触发ARFoundation和ARSubsystems包的安装,如下图所示:
开发包安装完毕,可以在层级管理器,资源管理器和项目设置中看到XR相关的信息,如下图所示:
现在我们可以通过层级管理器的右键菜单中的XR子菜单创建AR游戏对象了。
初始化场景
AR场景的摄像机由ARSession Origin管理,所以需要删除默认场景的MainCamera,通过层级管理器的XR菜单,创建如下图所示的游戏对象。
ARSession 和 ARSession Origin游戏对象自带了对应的脚本组件,并有默认的设置。需要注意的是,ARSession Origin下的ARCamera的ClearFlags不能用skybox,需要用SolidColor,如下图所示:
ARSession
ARSession游戏对象中的ARSession组件管理AR的开启和关闭,
ARSession组件可以挂在任意的GameObject上。禁用ARSession将停止AR系统的各种检测运算。ARSession提供了一个静态的协程方法CheckingAvailability,可以查询设备是否支持AR。下面的代码自定义一个脚本组件用来查询设备是否支持AR,注意Start函数的返回值修改为IEnumerator,以实现异步查询。
publicclass MyComponent : MonoBehaviour
[SerializeField] ARSessionm_Session;
IEnumerator Start() {
if ((ARSession.state ==ARSessionState.None) ||
(ARSession.state ==ARSessionState.CheckingAvailability))
{
yield returnARSession.CheckAvailability();
}
if (ARSession.state ==ARSessionState.Unsupported)
{
// Start somefallback experience for unsupported devices
}
else
{
// Start the ARsession
m_Session.enabled =true;
}
}
}
AR Session Origin
ARSessionOrigin游戏对象中的ARSessionOrigin组件处理AR世界坐标系到Unity坐标系的转换;ARPlaneManager处理平面检测;ARRaycastManager负责AR世界中的射线碰撞;
AR Camera
ARCamera处理摄像机的纹理捕获,镜头触发的画面移动由ARPose Driver完成。
平面检测
目前的默认设置已经具备平面检测能力,在这基础上我们需求进行一些交互,点击屏幕任意点,如果点在平面上,放置设定的3D模型到点的位置。
新建一个脚本组件,挂在ARSession Origin游戏对象上。其内容如下:
usingSystem.Collections.Generic;
usingUnityEngine;
usingUnityEngine.XR.ARFoundation;
usingUnityEngine.XR.ARSubsystems;
[RequireComponent(typeof(ARRaycastManager))]
publicclass PlaceOnPlane : MonoBehaviour
{
[SerializeField]
[Tooltip(“Instantiatesthis prefab on a plane at the touch location.”)]
GameObject m_PlacedPrefab;
///
/// The prefab toinstantiate on touch.
///
public GameObjectplacedPrefab
{
get { returnm_PlacedPrefab; }
set { m_PlacedPrefab =value; }
}
///
/// The object instantiatedas a result of a successful raycast intersection with a plane.
///
public GameObjectspawnedObject { get; private set; }
void Awake()
{
m_RaycastManager =GetComponent();
}
bool TryGetTouchPosition(outVector2 touchPosition)
{
#ifUNITY_EDITOR
if(Input.GetMouseButton(0))
{
var mousePosition =Input.mousePosition;
touchPosition = newVector2(mousePosition.x, mousePosition.y);
return true;
}
#else
if (Input.touchCount >0)
{
touchPosition =Input.GetTouch(0).position;
return true;
}
#endif
touchPosition = default;
return false;
}
void Update()
{
if(!TryGetTouchPosition(out Vector2 touchPosition))
return;
if(m_RaycastManager.Raycast(touchPosition, s_Hits,TrackableType.PlaneWithinPolygon))
{
// Raycast hits aresorted by distance, so the first one
// will be theclosest hit.
var hitPose =s_Hits[0].pose;
if (spawnedObject ==null)
{
spawnedObject =Instantiate(m_PlacedPrefab, hitPose.position, hitPose.rotation);
}
else
{
spawnedObject.transform.position= hitPose.position;
}
}
}
static Lists_Hits = new List();
ARRaycastManagerm_RaycastManager;
}
解析:
1.获取ARRaycastManager组件
2.获取触摸点,Raycast查询是否碰撞到AR平面。
3.如果碰撞到平面,创建模型实例,并设置位置到碰撞点。
发布测试
点击菜单File=> Build Setting, 切换Platform到iOS,点击build导出XCode工程,如下图所示:
打开Unity-iPhone.xcodeproj工程,在Xcode的账号设置中登录已注册iDP的账号,插入iPhone手机,并选择target为此手机,调整DeploymentTarget为11.0以上,如下图所示。
最后点击三角箭头启动程序,XCode自动编译并运行程序到手机上,最终效果如下图所示:
参考资料
暂无评论内容