大咖介紹
什麼是AR技術
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自動編譯並運行程序到手機上,最終效果如下圖所示:
參考資料
https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@4.1/manual/index.html