之前看过很多各路大佬写的东西,发现记不住,用的时候还得去搜大佬的文章再看。所以来写点东西,帮助自己记忆和查看。如果你要学习ARfoundation的话,推荐下面这个链接的大佬文章。
https://blog.csdn.net/yolon3000?t=1
建议使用Unity2019.3.0,window->PackageManager安装ARfoundation包和ARSubsystems包,我使用的是,Preview.8-3.1.0版本。 当时好像经过几次测试,发现只有这个版本的模型识别是可以用的,不知道什么原因,最后归结为版本不稳定。同时还得安装ARfoundation依赖包,就是ARkit(苹果)或者ARcore(安卓),因为ARfoundation只是为了方便开发而做的一层封装,在运行时自动判断运行环境来选择调用底层API。实现一次开发可以部署不同平台的目的。以下内容都是基于运行设备为苹果写的。
File->BuildSetting 切换平台为IOS。PlayerSetting设置相关项。设置目标设备、系统最低版本要求(ios11.0才支持AR)、修改框架为ARM64.(下图第一个标注的项是在设备中请求允许使用摄像机时显示的话。)
Hierarchy面板删除Camera,新建(鼠标右键->XR)ARsessionOrigin和ARsession两个物体。在ARsessionOrigin下找到子物体ARcamera,将其tag设为MainCamera(非必须)。新建任意物体放于摄像机前,就可以打包看看效果了。这两个物体就是AR应用的必备物体。它们的用途上文提到的链接里有一篇写的很清楚。个人觉得有用的是ARsession.state可以获取Session当前状态,例如正在检测设备可用性、AR软件正在安装(arcore或arkit)、AR可用并已经准备好等状态。ARcamer挂载的ARCameraManager组件有两个勾选框,FocusMode对焦模式、LightEstimationMode光照估计模式。
ARsessionOrigin添加两个脚本组件:ARPlanManagere(用于平面检测)和ARRaycastManager(用于射线检测)。做一些准备工作。创建ARDefaulPlan制作其预制体,并填入ARPlanManagere的PlanPrefab栏(这一栏不填也可以,就是看不到检测到的平面,对功能没有影响。如果给ARDefaulPlan的meshrenderer添入官方提供的OcclusionMaterial材质,就实现了真实物体遮挡功能)。制作一个sphere预制体,并设置缩放为0.1。制作一个button。随便找一个模型。编写如下脚本。添加给ARsessionOrigin。ARsessionOrigin面板如下图三。
这个脚本实现的功能是一直做射线检测,如果击中检测到的面就出现sphere光标物体,在击中状态下点击屏幕就会在打击点创建一个物体,并关闭射线检测、关闭平面检测、关闭之前检测到的面。点击按钮重置,删除物体,开启射线检测、开启平面检测、开启之前检测到的面。
其实这个脚本中重要的就两句话,其它的都无所谓。
ARsessionOrigin添加ARPointCloudManager脚本,并创建ARdefaultPointCloud预制体填入ARPointCloudManager的PointCloudPrefab栏位。打包就可以看到识别环境的特征点了。这个功能主要是用来让程序认识周围环境的。
用于稳定平面和虚拟物体。直接调用API:
想要稳定一个虚拟物体时,只需要让虚拟物体成为一个参考点的子物体就可以了。使用注意:
project面板鼠标右键->创建->XR ,可以看到两个选项,参考图像库(reference image library)和参考对象库(reference Object library),选择Reference Image Library,找一张图标添加进去并按下图设置(名字可以随便起、size为要识别的真实图片大小,选填)
在Resources文件夹新建一个与图片库中某一图片同名的物体预制体。ARsessionOrigin添加ARTrackedImageManager脚本,将新建的图片库填入SerializedLibrary栏。Max Number Of Moving Images设置同时可以追踪的图片数量上限。这时你可以在TrackedImagePrefab栏中填入Resources中刚刚建好的预制体,打包测试。如果想自定义一些功能就把TrackedImagePrefab栏空中并编写如下脚本添加给ARsessionOrigin。
这个脚本实现的功能是识别参考图像库中不同的图片预制不同的物体,在图片追踪丢失时删除物体。args.updated数组储存了当前识别的图片追踪体,包括刚识别的和刚刚丢失的。本来还有两个数组 args.added和args.removed,其实在删除丢失识别图像的物体时只需要遍历args.removed数组,用其名字在字典中检索对应物体删除就可以了(不必像我写的这样在args.updated中判断图片追踪体状态)。但是不知道为啥,测试了很多次args.removed数组的数量是有变化的,就是取不到数组中的数据,所以才用了上面代码中写的这种方法。
开启(ARcamera对象->ARcameraManager脚本->LightEstimationMode属性)关照估计功能。表现如下脚本并挂载与场景的灯光组件上。
具体意思我的理解是FramChanged每帧都被调用,把设备分析出的相关数据存储到 args.lightEstimation 中。这些数据会根据设备的不同有所区别,苹果只评估代码中写到的强度和色温,安卓会评估强度、颜色(args.lightEstimation.colorCorrection.Value )、和方向。
在你想放置反射球的位置直接创建一个AR的反射球就可以,反射效果不会很理想,只是通过反射的颜色可以大致判断是周围真实环境。
声明:
AREnvironmentProbeManager m_EnvironmentProbeManager;AREnvironmentProbeManager为官方组件需赋予ARsessionOrigin
AREnvironmentProbe m_Probe;//反射球
创建:
//创建AR环境反射球
//1、反射探头的位置应当放在需要反射的虚拟物体顶部中央,高度应该为虚拟物体高的两倍。这可以确保反射探头下部与虚拟物体下部对齐,并捕获到虚拟物体放置的平面的环境信息。
//2、反射探头的长与宽应该为虚拟物体长与宽的三倍,确保反射探头能捕获到虚拟物体周边的环境信息。
//3、反射探头可以朝向任何方向,但是,Unity的反射探头只支持轴对齐模式,因此,最好在放置时就设置成轴对齐。
m_Probe = m_EnvironmentProbeManager.AddEnvironmentProbe(ProbePose, new Vector3(0.6f, 0.6f, 0.6f), new Vector3(1.0f, 1.0f, 1.0f));
AddEnvironmentProbe函数参数:Pose(ARfoudation类,空间姿态)指定了放置的位置与方向,Scale指定了相对于Session空间的比例,Size指定了反射探头可探测的环境范围。
和图片识别差不多,ARsessionOrigin添加ARTrackedObjectManager填入创建好的参考对象库和TrackedObjectPrefab就可以识别。至于自定义预制脚本也和图片识别的差不多,不多做说明了。
需要说明的是,参考图片库中直接填入图片就可以,而参考对象库需要填入的是要识别物体的扫描数据文件(.arobject)。生成这个文件需要使用的一个App,这个app不能直接下载,得先下工程文件,然后生成在苹果手机中。在下述链接中可以找到下载地址和使用以及打包得方法。特别提示,在我下载这个app工程文件得时候,从window下载xcode文件在mac打包报错,在mac下载就顺利安装了。
其实经过测试不建议使用Arfoundation(也就是ARkit的原生)的图片和对象识别,还是使用vuforial的识别准确度、位置等信息都更准(不好得地方就是操作太繁琐了)。