判斷 session 可用性和設備支持
在啓動 AR 之前,通常需要先判斷 session 是否可用以及當前設備是否支持所需的 AR 功能。本文介紹瞭如何進行這些檢查。
開始之前
- 通過 ARSession 簡介 瞭解 session 的基本概念、組成和工作流程
- 通過 設備支持和報告 瞭解 Unity 中設備支持和 session 報告的基礎知識
- 瞭解如何 創建 session
在啓動流程中獲取報告
如果組裝之後直接啓動了 session,可以通過 StateChanged 事件獲取 session 報告。
需要在 session start 之前訂閱 StateChanged 事件,通常在 Awake() 中完成訂閱是安全的:
void Awake()
{
Session.StateChanged += HandleSessionStateChange;
}
在事件處理中需要關注的 session 的狀態包括:Ready 和 Broken。Ready 狀態說明 session 已經成功啓動,也即說明 session 在當前設備上可用。Broken 狀態說明 session 啓動失敗,也即說明 session 在當前設備上不可用。
Broken 狀態並不總是在設備不受支持的時候出現。所以還需要使用 SessionReport.BrokenReason 獲取具體的失敗原因。
void HandleSessionStateChange(ARSession.SessionState status)
{
if (status == ARSession.SessionState.Ready)
{
// session 在當前設備上可用
}
else if (status == ARSession.SessionState.Broken)
{
// session 在當前設備上不可用
if (Session.Report.BrokenReason == SessionReport.SessionBrokenReason.NoAvailabileFrameSource ||
Session.Report.BrokenReason == SessionReport.SessionBrokenReason.FrameFilterNotAvailabile)
{
// 所選組件不受當前設備支持
}
else
{
// 設備無關的原因
}
}
}
出現 SessionReport.SessionBrokenReason.NoAvailabileFrameSource 和 SessionReport.SessionBrokenReason.FrameFilterNotAvailabile 這兩種原因,說明 session 組件在當前設備上不可用;而其它原因通常是設備無關的。嚴格來說,出現這兩種原因意味着當前配置(且僅該配置)下的 AR 功能無法在該設備上運行。配置指 session 物體中選擇的功能和設置。可以從 Report 中獲得詳細的可用性報告。
對於 SessionReport.SessionBrokenReason.NoAvailabileFrameSource 的情況,如果在啓動 session 時聯網更新設備列表時發現設備已被支持,session 有可能自動恢復。
在啓動前獲取報告
如果希望在 session 啓動前做出判斷,並根據具體情況決定是否啓動 session,可以手動調用 Assemble() 並使用 AssembleUpdate 事件獲取組件可用性報告。
需要在 session assemble 之前訂閱 AssembleUpdate 事件,
Session.AssembleUpdate += OnAssembleUpdate;
在組裝第一階段,仍然可用利用 ARSession.SessionState 和 Report 來判斷 session 受支持的情況。但是第二階段的報告不會更新到 session 中。
因此一般手動調用 Assemble() 時,需要在 AssembleUpdate 事件中處理組件可用性報告,從而判斷 session 在當前設備上是否可用。
需要重點關注 SessionReport.AvailabilityReport.FrameSources 列表中組件的可用性。如果有任何一個 frame source 組件是可用的,那麼 SessionReport.AvailabilityReport.FrameSources 部分在當前設備上就是可用的。
同時還需要關注報告中的 SessionReport.AvailabilityReport.FrameFilters 列表中組件的可用性。但是判斷標準根據組裝選項不同,會要求所有 frame filter 可用,或是任意數量的 frame filter 可用。默認選項下,要求所有 frame filter 可用。
在默認配置下,可以使用如下代碼判斷 session 組件在當前設備上是否可用:
void OnAssembleUpdate(SessionReport.AvailabilityReport report)
{
if (report.FrameSources.Any(f => f.Availability == SessionReport.AvailabilityReport.AvailabilityStatus.Available) &&
report.FrameFilters.All(f => f.Availability == SessionReport.AvailabilityReport.AvailabilityStatus.Available))
{
Session.AssembleUpdate -= OnAssembleUpdate;
// session 組件在當前設備上可用,可以啓動 session
Session.StartSession();
}
else
{
// session 組件在當前設備上不可用
}
if (report.PendingDeviceList.Count <= 0)
{
Session.AssembleUpdate -= OnAssembleUpdate;
}
}
注意 AssembleUpdate 事件可能會觸發兩次。上面的代碼示例中,會在確認組件可用後取消訂閱事件。
這種判斷方法沒法判斷 session 啓動過程中可能出現的其它錯誤,但這些錯誤通常是設備無關的,如有需要可以在啓動 session 後通過 StateChanged 事件進行補充判斷。
session 組件不可用時的選擇
在應用開發中,一般都希望對儘量多的設備提供兼容支持。因此當 session 組件在當前設備上不可用時,可以考慮以下幾種選擇:
降級使用其它 AR 功能
通過修改 session 組件配置,選擇當前設備支持的 AR 功能。可以參考 創建 session 瞭解如何修改 session 組件配置。提供非 AR 體驗
在 session 組件不可用時,提供一個非 AR 的體驗。比如在導航場景下,如果 AR 導航無法實現,提供傳統2D導航是非常有用的。提示用戶更換設備
在某些應用場景下,用戶可能會使用不支持 AR 功能的設備。此時可以提示用戶更換設備以獲得更好的體驗。
在選擇這些方案時,可以結合應用的具體需求和用戶羣體進行權衡。在 AR 應用中,如果部分設備確實無法提供 AR 或降級方案,仍然需要提供一個良好的用戶提示信息,以便讓用戶瞭解當前設備的限制。
後續步驟
- 瞭解 控制 session 執行 的方法
- 瞭解 幀數據源及運行時選取
- 另外,您還可以通過下面這些示例來了解獲取報告之後的應用場景:
- Workflow_ARSession 示例 使用了 StateChanged 事件並對 Broken 狀態提供了 UI 提示,同時還使用 AssembleUpdate 事件在 UI 上展示了每個組件的可用性
- SpatialMap_Sparse_AllInOne 示例使用 AssembleUpdate 事件對設備支持進行了提前判斷和不可用提示
- MotionTracking_DeviceMotionAndPlaneDetection 示例使用了 StateChanged 事件並對 Broken 狀態提供了 UI 提示
- MegaBlock_Basic 示例使用了 StateChanged 事件並對 Broken 狀態提供了 UI 提示