最近因为做的几个项目需要用的ARKit 就整理下学习的
Unity ARKit Plugin 插件下载
判断设备是否支持ARKit
//方法1
ARKitSessionConfiguration configuration = new ARKitSessionConfiguration();
Debug.Log(configuration.IsSupported.ToString());
//方法2
ARKitWorldTrackingSessionConfiguration configuration2 = new ARKitWorldTrackingSessionConfiguration();
Debug.Log(configuration2.IsSupported.ToString());
在开发过程中可用ARKitRemote 发布到真机和mac 调试 如果不会发布ios 可查看之前的一片文章 Unity测试发布iOS
打包发布到 ios 移动端运行app 后mac
这样就可以通过无线 每次手机运行这个程序和电脑远程调试了
在Remote 测试时会报错 这是插件的问题我们可以修改UnityARCameraManager 脚本
相机添加插件中 UnityARCameraManager 脚本并把相机拖拽到脚本变量
UnityARGeneratePlane 用于检测到平面时现实的平面
PointCloudParticleExample 用于在检测时显示的点云
using UnityEngine;
using UnityEngine.XR.iOS;
public class ARSessionController : MonoBehaviour {
private UnityARSessionNativeInterface m_session;
// Use this for initialization
void Start () {
m_session = UnityARSessionNativeInterface.GetARSessionNativeInterface();
}
///
/// 开启检测
///
public void onRunClick(){
m_session.Run(); //默认配置运行
}
///
/// 暂停检测
///
public void OnPauseClick(){
m_session.Pause();
}
///
/// 重制并开启追踪检测
///
public void ResetAndRun(){
ARKitWorldTrackingSessionConfiguration configuration = new ARKitWorldTrackingSessionConfiguration();
configuration.alignment = UnityARAlignment.UnityARAlignmentCamera; //检测类型
configuration.planeDetection = UnityARPlaneDetection.Horizontal; //平面类型
configuration.enableLightEstimation = true; //光照信息
configuration.getPointCloudData = true; //点云
//m_session.RunWithConfig(configuration);
m_session.RunWithConfigAndOptions(configuration, UnityARSessionRunOption.ARSessionRunOptionResetTracking); //重制追踪
}
///
/// 移除并开启追踪检测
///
public void RemoveAndRun(){
ARKitWorldTrackingSessionConfiguration configuration = new ARKitWorldTrackingSessionConfiguration();
configuration.alignment = UnityARAlignment.UnityARAlignmentGravity; //检测类型
configuration.planeDetection = UnityARPlaneDetection.Horizontal; //平面类型
configuration.enableLightEstimation = true; //光照信息
configuration.getPointCloudData = true; //点云
//m_session.RunWithConfig(configuration);
m_session.RunWithConfigAndOptions(configuration, UnityARSessionRunOption.ARSessionRunOptionRemoveExistingAnchors); //移除之前的平面
}
///
/// 重制并关闭检测
///
public void ResetAndClose(){
ARKitWorldTrackingSessionConfiguration configuration = new ARKitWorldTrackingSessionConfiguration();
configuration.alignment = UnityARAlignment.UnityARAlignmentGravity; //检测类型
configuration.planeDetection = UnityARPlaneDetection.None; //平面类型
configuration.enableLightEstimation = true; //光照信息
configuration.getPointCloudData = false; //点云
//m_session.RunWithConfig(configuration);
m_session.RunWithConfigAndOptions(configuration, UnityARSessionRunOption.ARSessionRunOptionResetTracking); //重制之前的平面
}
///
/// 移除并关闭检测
///
public void RemoveAndClose()
{
ARKitWorldTrackingSessionConfiguration configuration = new ARKitWorldTrackingSessionConfiguration();
configuration.alignment = UnityARAlignment.UnityARAlignmentGravity; //检测类型
configuration.planeDetection = UnityARPlaneDetection.None; //平面类型
configuration.enableLightEstimation = true; //光照信息
configuration.getPointCloudData = false; //点云
//m_session.RunWithConfig(configuration);
m_session.RunWithConfigAndOptions(configuration, UnityARSessionRunOption.ARSessionRunOptionRemoveExistingAnchors); //移除之前的平面
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.iOS;
public class HitResultController : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved)
{
Vector3 screenPos = Camera.main.ScreenToViewportPoint(touch.position); //将屏幕坐标转为视口坐标
ARPoint point = new ARPoint
{
x = screenPos.x,
y = screenPos.y
};
//ARHitTestResultType 枚举检测平面类型
ARHitTestResultType[] resultTypes ={
ARHitTestResultType.ARHitTestResultTypeFeaturePoint, //与最近特征点相交的结果类型
ARHitTestResultType.ARHitTestResultTypeHorizontalPlane,
ARHitTestResultType.ARHitTestResultTypeExistingPlane, //与现有平面定位点相交的结果类型。
ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent //考虑到平面的范围,与现有平面锚点相交的结果类型
};
//只要检测到枚举类型平面中的一种 就保存检测到的信息
foreach (ARHitTestResultType resultType in resultTypes)
{
List hitTestResults = UnityARSessionNativeInterface.GetARSessionNativeInterface().HitTest(point, resultType); //获取一个点附近的检测信息
}
}
}
}
}
hitTestResults 中就存在真实世界中的信息数据
声明两个 GameObject
public GameObject Obj;
private GameObject currentObj;
要放置的物体拖到 Obj 在 foreach 中添加脚本
//只要检测到枚举类型平面中的一种 就保存检测到的信息
foreach (ARHitTestResultType resultType in resultTypes)
{
List hitTestResults = UnityARSessionNativeInterface.GetARSessionNativeInterface().HitTest(point, resultType); //获取一个点附近的检测信息
if (currentObj==null)
{
currentObj = Instantiate(Obj);
}
currentObj.transform.position = UnityARMatrixOps.GetPosition(hitTestResults[0].worldTransform); //获取position
currentObj.transform.rotation = UnityARMatrixOps.GetRotation(hitTestResults[0].worldTransform);
}
创建材质球并附上贴图
创建plane预制体 拖到
拖入创建的预制体 设置点云最大量和大小
插件中提供了预制体通过shadr 可显示阴影
在Directional Light 添加 UnityARAmbient 脚本可渲染真实世界光照
是通过shader实现的 更换插件提供的平面预制体可实现
创建预制体 添加LineRenderer组件 并创建脚本控制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LineController : MonoBehaviour {
private LineRenderer lineRenderer;
private List points=new List();
// Use this for initialization
void Start () {
lineRenderer = this.GetComponent();
}
public void AddPoint(Vector3 pointt){
Vector3 currentPos = pointt + (Camera.main.transform.forward * 0.2f);
points.Add(currentPos);
updateRanderer();
}
void updateRanderer(){
lineRenderer.positionCount = points.Count;
lineRenderer.SetPositions(points.ToArray());
}
public void SetColor(Color color){
Material material = new Material(lineRenderer.material);
material.SetColor("_Color", color);
lineRenderer.material = material;
}
}
相机添加插件中 UnityARCameraNearFar 脚本 可将相机的 near far 值复制给ar 相机
创建脚本FrameUpdateController 用来检测相机事件 把刚才创建的lineRenderer 赋值上去
using UnityEngine;
using System.Collections;
using UnityEngine.XR.iOS;
public class FrameUpdateController : MonoBehaviour
{
public GameObject linObj;
private LineController lineController;
private bool isDrawing; //是否开始绘画
private Vector3 previousPos; //上次位置
private void OnEnable()
{
UnityARSessionNativeInterface.ARFrameUpdatedEvent += ARFrameUpdate;
}
private void OnDestroy()
{
UnityARSessionNativeInterface.ARFrameUpdatedEvent -= ARFrameUpdate;
}
///
/// 相机刷新时
///
/// Camera.
void ARFrameUpdate(UnityARCamera cam){
Matrix4x4 matrix = new Matrix4x4();
matrix.SetColumn(3, cam.worldTransform.column3);
Vector3 pos = UnityARMatrixOps.GetPosition(matrix); //通过矩阵类型转换 获取相机位置
print(pos);
if (isDrawing&&Vector3.Distance(pos,previousPos)>0.01f)
{
lineController.AddPoint(pos);
previousPos = pos;
}
}
private void OnGUI()
{
if (GUI.Button(new Rect(100,200,200,100),"Start"))
{
isDrawing = true;
lineController = Instantiate(linObj, this.transform).GetComponent();
}
if (GUI.Button(new Rect(100, 400, 200, 100), "Pause"))
{
isDrawing = false;
}
if (GUI.Button(new Rect(100, 600, 200, 100), "ChangeColor"))
{
Color color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));
lineController.SetColor(color);
}
}
}
可通过GUI Button 点击开始进行绘画
获取相机位置
UnityARKitScene 点击放置物体
UnityParticlePainter 空间例子系统画点 (空间作画)
UnityARBallz 平面小球移动与碰撞(模拟小球平掉落到另外平面)
UnityARShadows 在平面显示物体阴影
UnityAROcclusion 遮光材料遮挡物体
FocusSquareScene 视点聚焦 (检测时给其动态效果)
AddRemoveAnchorScene 通过Anchor添加删除物体