Table of Contents

Unity AR 的入口 —— AR Session

AR 會話(session)是所有 AR 功能的入口,通過以下內容您將瞭解 AR Session 的基本概念、組成、運行流程以及它與 Unity AR Foundation 的 AR Session 有什麼關係。您還會瞭解到在 Unity 中,EasyAR Sense 的數據流到底是如何工作的。

AR Session 是什麼

所有 AR 流程(例如物體跟蹤)都是在原生庫,即 EasyAR Sense 內部執行的。session 是 Unity 中 AR 功能的主要入口點。它管理 AR 系統的運行過程和狀態,包括從物理相機和傳感器中讀取數據、分析真實世界、驅動場景中虛擬攝像機等其它部分物體的移動和渲染等。

flowchart LR
  A((圖像<br>和其它數據))
  B[Session]
  C([Camera])
  O([Origin])
  T([Target])
  A --> B
  B -. transform .-> C
  B -. transform .-> O
  B -. transform .-> T

[可選] EasyAR 的 session 與 AR Foundation 的 session

EasyAR 的 session 是 Unity 中使用 EasyAR 的核心組件,可以獨立於任何第三方或系統 AR 功能運行。而 AR Foundation 的 session 是 Unity XR 框架的一部分,只能使用 Unity XR 插件(如 ARKit 或 ARCore)提供的功能。

flowchart TD
  A1[EasyAR<br>AR Session]
  A2[EasyAR Sense]
  A1 --> A2

  B1[AR Foundation<br>AR Session]
  B2[ARKit Plugin]
  B3[ARCore Plugin]
  B1 --> B2
  B1 --> B3

使用 EasyAR 時,通常並不需要同時安裝和使用 AR Foundation。比如圖像跟蹤功能,運動跟蹤功能等等,都是由 EasyAR Sense 獨立提供的。

在某些情況下,可能需要將 EasyAR Sense 與 AR Foundation 結合使用,以利用 AR Foundation 提供的額外功能(比如在部分設備上的平面檢測)和接口。在這種情況下,EasyAR Sense 通過 AR Foundation 提供的接口與 Unity 引擎進行交互。

但是,由於 EasyAR 提供了比系統 AR 更多的功能和更完善的設備適配,獨立使用 AR Foundation 通常無法達到與 EasyAR 相同的效果。

session 的組成

一個典型的 session 主要由以下部分組成:

  • frame source:提供物理相機圖像和傳感器數據的組件,有時這些組件也會提供運動跟蹤數據。比如 CameraDeviceFrameSourceMotionTrackerFrameSource
  • frame filter(s):提供特定AR功能的組件,比如 ImageTrackerFrameFilter
  • camera:場景中的虛擬攝像機對象
  • origin:運動跟蹤的原點對象
附註

在 AR Foundation 的概念中,運動跟蹤被作爲必選功能,因此它始終會提供一個 origin。
而在 EasyAR 系統中,運動跟蹤是一個可選的功能,因此 origin 也是可選的。

[可選] session 的數據流

數據流 是 EasyAR Sense 的核心概念之一。它不影響您在 Unity 中開發 AR 應用。如果您想要更加深入地理解 session 的工作原理,可以閱讀本節內容。

在 Unity 中,一個 session 通常表達了一個 EasyAR Sense 的數據流。

flowchart LR
  S[Frame Source]
  R[Input Frame Recorder<br>Video Input Frame Recorder]
  ift[iFrameThrottler]
  iff[iFrameFork]
  i2f[i2FAdapter]
  fb[fbFrameFork]  
  i2o[i2OAdapter]

  FOT[Object Tracker]
  FIT[Image Tracker]
  FMT[Mega Tracker]
  FSSM[Sparse Spatial Map]
  FST[Surface Tracker]
  FDS[Dense Spatial Map]
  FCR[Cloud Recognizer]
  
  ofj[oFrameJoin]
  off[oFrameFork]
  ofb[oFrameBuffer]

  O(( ))
  ODS(( ))
  OCR(( ))

  S ==> R ==> ift ==> iff
  iff --> i2f
  i2f --> fb
  fb -.-> FOT -.-> ofj
  fb -.-> FIT -.-> ofj
  iff ==> i2o ==> ofj ==> off ==> ofb ==> O
  iff -.-> FMT -.-> ofj
  iff -.-> FSSM -.-> ofj
  iff -.-> FST -.-> ofj
  iff -.-> FDS -.-> ODS
  iff -.-> FCR -.-> OCR
  off --> i2f
  ofb --> ift

這個數據流是在 session 啓動過程中創建的,圖中除加粗數據通路外,其它部分是否連接取決於啓動過程中啓用的 AR 組件。

因此,通過修改 session 中啓用的組件,可以靈活改變數據流的結構和功能,也可以很方便地同時啓用多個 AR 功能。而這個方法將在接下來的段落中詳細介紹。

session 的流程

flowchart LR
  i[初始化<br>Initialize]
  a[組裝<br>Assemble]
  starta["啓動(已組裝的)<br>StartSession(Assembled)"]
  start[啓動<br>StartSession]
  update((更新<br>update))
  stop[停止<br>StopSession]
  di[反初始化<br>Deinitialize]

  i --> a --> starta --> update --> stop --> di
  i --> start --> update

  • 初始化
    初始化是使用使用 license key 啓動 EasyAR Sense 的過程,在初始化之前,只有極少部分 EasyAR Sense 的接口可以使用。初始化之後,AR 功能纔會被激活。

  • 組裝(Assembling)
    組裝過程會根據組裝選項的配置,從場景中挑選合適的組件,並將它們連接成一個整體工作單元。這個過程通常是在啓動時自動完成的,但也可以在啓動之前手動調用組裝接口來完成這個過程。組裝完成後,可以通過啓動已組裝的 session 來跳過組裝過程,從而加快啓動速度。
    組裝過程還有一個重要的用途就是判斷AR組件以及輸入源的可用性,並在所有候選輸入中選擇最合適的輸入源。這一步驟也可以用來判斷當前 session 是否可以在當前設備上運行。

    組裝過程分成兩個階段

    1. 第一階段會啓動設備支持列表更新並根據配置等待固定時間後開始組裝。如果在第一階段等待後設備支持列表已經更新完成,那麼組裝過程就結束了;
    2. 否則組裝過程會進入第二階段,第二階段會在設備支持列表更新完成後執行。在這一階段中,如果可用 frame source 從第一階段的沒有可用 frame source 變成了存在可用 frame source,且 session 在第一階段之後啓動失敗,則會嘗試重新啓動 session。

    無論第一階段設備列表是否完成更新,session 都會在第一階段完成後繼續執行後續步驟。

  • 啓動
    啓動是開始 AR 功能運行的過程。在啓動之前,AR 功能組件不會處理任何數據。正常啓動之後,session 會開始控制場景中的部分物體移動,並在使用部分輸入源時控制物理相機圖像的渲染。

  • 更新
    更新過程在 Unity 的渲染循環的每幀執行。更新過程會根據當前使用的AR功能的運行結果,每幀修改虛擬攝像機(部分輸入源)、原點以及跟蹤目標的 transform。不同設備上更新過程的執行時間點並不是相同的,但一定會在渲染之前執行。

  • 停止
    停止會終止 AR 功能的運行,場景中的物體將不再被 session 控制,輸入源的數據也不會被處理。

  • 反初始化
    反初始化會釋放部分全局資源(不會卸載動態庫)。反初始化之後,AR 功能組件將無法使用。

附註

所有 AR 功能只能在 ARSession.StartSession 之後使用。

session 的默認生命週期

flowchart LR
  uload("BeforeSceneLoad")
  ustart("MonoBehaviour.Start")
  udestroy("MonoBehaviour.OnDestroy")
  oi{Initialize<br>OnStartup}
  ostart{AutoStart}
  i[初始化<br>Initialize]
  start[啓動<br>StartSession]
  update((更新<br>update))
  stop[停止<br>StopSession]
  
  uload -.-> ustart -.-> udestroy
  uload --> oi -. true .-> i
  ustart --> ostart -. true .-> start
  udestroy --> stop
  i --> start --> update --> stop

session 的生命週期一般由接口調用的時間決定。採用默認設置時,session 會在以下時間點自動執行:

session 狀態

ARSession.State 描述了 session 的狀態。一個 session 有以下幾種狀態:

狀態 描述
None 初始狀態,session 未啓動或組裝
Broken 組裝失敗等原因 session 被破壞
Assembling 在組裝過程中,組裝過程通常可能持續幾幀
Assembled 成功完成組裝,但尚未啓動
Ready session 成功啓動,這個狀態只會持續一幀
Running session 在運行中
Paused session 暫停運行

通常 session 的狀態會在調用啓動和停止等接口時發生變化。運行過程中,如果出現嚴重錯誤,session 也可能進入 Broken 狀態。進入 Broken 狀態的 session 無法恢復運行,必需調用停止後重新啓動。

可以通過 session 的狀態瞭解當前 session 是否出於可用狀態。絕大多數功能只有在 ReadyRunning 狀態下才能使用。

運動跟蹤狀態

ARSession.TrackingStatus 描述了 session 的運動跟蹤跟蹤狀態,它表示設備運動跟蹤的質量,有這幾種狀態:

狀態 描述
Optional<MotionTrackingStatus>.Empty 運動跟蹤功能未啓用或 session 未運行
NotTracking 運動跟蹤結果不可用,原因可能是正在初始化,跟蹤丟失或者正在重定位
Limited 運動跟蹤是有效的,但是結果不太好,原因可能是當前區域紋理太弱或運動過快
Tracking 運動跟蹤質量好
附註

在 AR Foundation 的概念中,運動跟蹤被作爲必選功能,因此它的跟蹤狀態與 session 狀態合併在了一起。
而在 EasyAR 系統中,運動跟蹤是一個可選的功能,因此跟蹤狀態是獨立存在且可能爲空的。

其它 AR 功能的跟蹤狀態在哪

由於 AR 功能可能同時跟蹤複數個對象,因此圖像跟蹤狀態和其它 AR 功能的跟蹤狀態並不在 session 中,而是在跟蹤目標組件中。

可以使用 TargetController.IsTracked 瞭解跟蹤目標是否出於跟蹤狀態,或使用 TargetController.TargetFound 和TargetController.TargetLost 事件在跟蹤狀態變化時調整應用內容邏輯。

後續步驟

創建

控制運行

訪問組件和結果

組件參考