Table of Contents

判斷 session 可用性和裝置支援

在啟動 AR 之前,通常需要先判斷 session 是否可用以及當前裝置是否支援所需的 AR 功能。本文介紹了如何進行這些檢查。

開始之前

在啟動流程中獲取報告

如果組裝之後直接啟動了 session,可以透過 StateChanged 事件獲取 session 報告。

需要在 session start 之前訂閱 StateChanged 事件,通常在 Awake() 中完成訂閱是安全的:

void Awake()
{
    Session.StateChanged += HandleSessionStateChange;
}

在事件處理中需要關注的 session 的狀態包括:ReadyBrokenReady 狀態說明 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.NoAvailabileFrameSourceSessionReport.SessionBrokenReason.FrameFilterNotAvailabile 這兩種原因,說明 session 元件在當前裝置上不可用;而其它原因通常是裝置無關的。嚴格來說,出現這兩種原因意味著當前配置(且僅該配置)下的 AR 功能無法在該裝置上執行。配置指 session 物體中選擇的功能和設定。可以從 Report 中獲得詳細的可用性報告。

對於 SessionReport.SessionBrokenReason.NoAvailabileFrameSource 的情況,如果在啟動 session 時聯網更新裝置列表時發現裝置已被支援,session 有可能自動恢復。

在啟動前獲取報告

如果希望在 session 啟動前做出判斷,並根據具體情況決定是否啟動 session,可以手動呼叫 Assemble() 並使用 AssembleUpdate 事件獲取元件可用性報告。

需要在 session assemble 之前訂閱 AssembleUpdate 事件,

Session.AssembleUpdate += OnAssembleUpdate;

在組裝第一階段,仍然可用利用 ARSession.SessionStateReport 來判斷 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 或降階方案,仍然需要提供一個良好的使用者提示資訊,以便讓使用者了解當前裝置的限制。

後續步驟