建立空間感知系統資料提供者 — MRTK2

空間感知系統是一種可延伸的系統,可為應用程式提供真實世界環境的相關資料。 若要新增支援新的硬體平臺或新的空間感知資料形式,可能需要自訂資料提供者。

本文說明如何建立空間感知系統的 自訂資料提供者,也稱為空間觀察者。 此處顯示的範例程式碼來自 SpatialObjectMeshObserver 類別實作,這 適用于在編輯器中載入 3D 網格資料

注意

您可以在 資料夾中找到 Assets/MRTK/Providers/ObjectMeshObserver 此範例中使用的完整原始程式碼。

命名空間和資料夾結構

資料提供者可以透過下列兩種方式之一散發:

  1. 協力廠商附加元件
  2. Microsoft Mixed Reality工具組的一部分

將新資料提供者提交至 MRTK 的核准程式會依案例而有所不同,並且會在初始提案時進行通訊。 您可以藉由建立新的 功能要求 類型問題來提交提案。

協力廠商附加元件

Namespace

資料提供者必須有命名空間,才能減輕潛在的名稱衝突。 建議命名空間包含下列元件。

  • 產生附加元件的公司名稱
  • 功能區域

例如,Contoso 公司所建立和運送的空間感知資料提供者可能是「Contoso.MixedReality.Toolkit.SpatialAwareness」。

資料夾結構

建議將資料提供者的原始程式碼配置在資料夾階層中,如下圖所示。

範例資料夾結構

其中 ContosoSpatialAwareness 資料夾包含資料提供者的實作, [編輯器 ] 資料夾包含 inspector (,以及任何其他 Unity 編輯器特定程式碼) ,而 Profiles 資料夾包含一或多個預先設定的設定檔可編寫腳本的物件。

MRTK 提交

Namespace

如果將空間感知系統資料提供者提交至Mixed Reality Toolkit 存放庫,命名空間必須以 Microsoft.MixedReality.Toolkit (例如:Microsoft.MixedReality.Toolkit.SpatialObjectMeshObserver)

和 程式碼應該位於 MRTK/Providers 下的資料夾 (例如 :MRTK/Providers/ObjectMeshObserver) 。

資料夾結構

所有程式碼都應該位於 MRTK/Providers 下方的資料夾 (,例如:MRTK/Providers/ObjectMeshObserver) 。

定義空間資料物件

建立空間感知資料提供者的第一個步驟是判斷資料類型 (例如:網格或平面) 提供給應用程式。

所有空間資料物件都必須實作 IMixedRealitySpatialAwarenessObject 介面。

Mixed Reality Toolkit 基礎提供下列空間物件,可在新的資料提供者中使用或擴充。

實作資料提供者

指定介面和/或基類繼承

所有空間感知資料提供者都必須實 IMixedRealitySpatialAwarenessObserver 作 介面,以指定空間感知系統所需的最低功能。 MRTK 基礎包含 類別, BaseSpatialObserver 可提供此必要功能的預設實作。

public class SpatialObjectMeshObserver :
    BaseSpatialObserver,
    IMixedRealitySpatialAwarenessMeshObserver,
    IMixedRealityCapabilityCheck
{ }

注意

類別 IMixedRealityCapabilityCheck 會使用 SpatialObjectMeshObserver 介面來指出它提供 SpatialAwarenessMesh 功能的支援。

套用 MixedRealityDataProvider 屬性

建立空間感知資料提供者的重要步驟是將 MixedRealityDataProvider 屬性套用至 類別。 此步驟會在 [空間感知] 設定檔和 [名稱]、[資料夾路徑] 等專案中選取時,為數據提供者設定預設設定檔和平臺 () 。

[MixedRealityDataProvider(
    typeof(IMixedRealitySpatialAwarenessSystem),
    SupportedPlatforms.WindowsEditor | SupportedPlatforms.MacEditor | SupportedPlatforms.LinuxEditor,
    "Spatial Object Mesh Observer",
    "ObjectMeshObserver/Profiles/DefaultObjectMeshObserverProfile.asset",
    "MixedRealityToolkit.Providers")]
public class SpatialObjectMeshObserver :
    BaseSpatialObserver,
    IMixedRealitySpatialAwarenessMeshObserver,
    IMixedRealityCapabilityCheck
{ }

實作 IMixedRealityDataProvider 方法

定義 類別之後,下一個步驟是提供 介面的實作 IMixedRealityDataProvider

注意

類別 BaseSpatialObserver 透過 BaseService 類別,只提供方法的空白實作 IMixedRealityDataProvider 。 這些方法的詳細資料通常是特定的資料提供者。

資料提供者應該實作的方法如下:

  • Destroy()
  • Disable()
  • Enable()
  • Initialize()
  • Reset()
  • Update()

實作資料提供者邏輯

下一個步驟是實作特定的資料提供者介面來新增資料提供者的邏輯,例如 IMixedRealitySpatialAwarenessMeshObserver 。 資料提供者的這個部分通常是平臺特定的。

觀察變更通知

為了允許應用程式回應裝置對環境的瞭解變更,資料提供者會引發介面中所 IMixedRealitySpatialAwarenessObservationtHandler<T> 定義的通知事件。

  • OnObservationAdded()
  • OnObservationRemoved()
  • OnObservationUpdated()

下列範例中的 SpatialObjectMeshObserver 程式碼示範在新增網格資料時引發 和 事件。

// The data to be sent when mesh observation events occur.
// This member variable is initialized as part of the Initialize() method.
private MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> meshEventData = null;

/// <summary>
/// Sends the observations using the mesh data contained within the configured 3D model.
/// </summary>
private void SendMeshObjects()
{
    if (!sendObservations) { return; }

    if (spatialMeshObject != null)
    {
        MeshFilter[] meshFilters = spatialMeshObject.GetComponentsInChildren<MeshFilter>();
        for (int i = 0; i < meshFilters.Length; i++)
        {
            SpatialAwarenessMeshObject meshObject = SpatialAwarenessMeshObject.Create(
                meshFilters[i].sharedMesh,
                MeshPhysicsLayer,
                $"Spatial Object Mesh {currentMeshId}",
                currentMeshId,
                ObservedObjectParent);

            meshObject.GameObject.transform.localPosition = meshFilters[i].transform.position;
            meshObject.GameObject.transform.localRotation = meshFilters[i].transform.rotation;

            ApplyMeshMaterial(meshObject);

            meshes.Add(currentMeshId, meshObject);

            // Initialize the meshEventData variable with data for the added event.
            meshEventData.Initialize(this, currentMeshId, meshObject);
            // Raise the event via the spatial awareness system.
            SpatialAwarenessSystem?.HandleEvent(meshEventData, OnMeshAdded);

            currentMeshId++;
        }
    }

    sendObservations = false;
}

注意

類別 SpatialObjectMeshObserver 不會引發 OnObservationUpdated 事件,因為 3D 模型只會載入一次。 類別 WindowsMixedRealitySpatialMeshObserver 中的 實作提供引發所觀察網格之事件的範例 OnObservationUpdated

新增 Unity Profiler 檢測

效能在混合實境應用程式中非常重要。 每個元件都會增加應用程式必須考慮的一些額外負荷。 為此,所有空間感知資料提供者在內部迴圈中包含 Unity Profiler 檢測,以及經常使用的程式碼路徑非常重要。

建議您在檢測自訂提供者時實作 MRTK 所使用的模式。

        private static readonly ProfilerMarker UpdateObserverPerfMarker = new ProfilerMarker("[MRTK] WindowsMixedRealitySpatialMeshObserver.UpdateObserver");

        /// <summary>
        /// Requests updates from the surface observer.
        /// </summary>
        private void UpdateObserver()
        {
            using (UpdateObserverPerfMarker.Auto())
            {
                // Code to be measured.
            }
        }

注意

用來識別分析工具標記的名稱是任意的。 MRTK 使用下列模式。

「[product] className.methodName - 選擇性附注」

建議自訂資料提供者遵循類似的模式,以協助簡化分析追蹤時的特定元件和方法的識別。

建立設定檔和偵測器

在 Mixed Reality Toolkit 中,會使用設定檔來設定資料提供者。

定義設定檔

設定檔內容應該鏡像資料提供者的可存取屬性 (,例如:更新間隔) 。 每個介面中定義的所有使用者可設定屬性都應該包含在設定檔中。

如果新的資料提供者擴充現有的提供者,則會鼓勵基類。 例如,會 SpatialObjectMeshObserverProfile 擴充 MixedRealitySpatialAwarenessMeshObserverProfile ,讓客戶提供 3D 模型做為環境資料使用。

[CreateAssetMenu(
    menuName = "Mixed Reality Toolkit/Profiles/Spatial Object Mesh Observer Profile",
    fileName = "SpatialObjectMeshObserverProfile",
    order = 100)]
public class SpatialObjectMeshObserverProfile : MixedRealitySpatialAwarenessMeshObserverProfile
{
    [SerializeField]
    [Tooltip("The model containing the desired mesh data.")]
    private GameObject spatialMeshObject = null;

    /// <summary>
    /// The model containing the desired mesh data.
    /// </summary>
    public GameObject SpatialMeshObject => spatialMeshObject;
}

屬性 CreateAssetMenu 可以套用至設定檔類別,讓客戶能夠使用 [建立>資產>Mixed Reality工具> 組設定檔] 功能表來建立設定檔實例。

實作偵測器

設定檔偵測器是用來設定和檢視設定檔內容的使用者介面。 每個設定檔偵測器都應該擴充 BaseMixedRealityToolkitConfigurationProfileInspector 類別。

屬性 CustomEditor 會通知 Unity 要套用的資產類型。

[CustomEditor(typeof(SpatialObjectMeshObserverProfile))]
public class SpatialObjectMeshObserverProfileInspector : BaseMixedRealityToolkitConfigurationProfileInspector
{ }

() 建立元件定義

Mixed Reality Toolkit 會使用元件定義 (.asmdef) 檔案來指定元件之間的相依性,以及協助 Unity 減少編譯時間。

建議針對所有資料提供者及其編輯器元件建立元件定義檔案。

使用先前範例中的 資料夾結構 時,ContosoSpatialAwareness 資料提供者會有兩個 .asmdef 檔案。

第一個元件定義是用於資料提供者。 在此範例中,它會稱為 ContosoSpatialAwareness,而且會位於範例的 ContosoSpatialAwareness 資料夾中。 此元件定義必須指定 Microsoft.MixedReality.Toolkit 的相依性,以及它相依的任何其他元件。

ContosoInputEditor 元件定義會指定設定檔偵測器和任何編輯器特定的程式碼。 這個檔案必須位於編輯器程式碼的根資料夾中。 在此範例中,檔案會位於 ContosoSpatialAwareness\Editor 資料夾中。 此元件定義將包含 ContosoSpatialAwareness 元件的參考,以及:

  • Microsoft.MixedReality.Toolkit
  • Microsoft.MixedReality.Toolkit.Editor.Inspectors
  • Microsoft.MixedReality.Toolkit.Editor.Utilities

註冊資料提供者

建立之後,即可向要用於應用程式的空間感知系統註冊資料提供者。

選取空間物件網格觀察者

封裝和散發

散發為協力廠商元件的資料提供者具有開發人員喜好設定的封裝和散發的特定詳細資料。 可能,最常見的解決方案是產生 .unitypackage,並透過 Unity 資產存放區散發。

如果提交並接受資料提供者作為 Microsoft Mixed Reality Toolkit 套件的一部分,Microsoft MRTK 小組將會封裝並散發為 MRTK 供應專案的一部分。

另請參閱