共用方式為


建立空間感知系統數據提供者 - MRTK2

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

本文說明如何為空間感知系統建立 自定義數據提供者,也稱為空間觀察者。 此處所示的範例程式代碼來自 SpatialObjectMeshObserver 類別實作,其 適用於在編輯器中載入 3D 網格數據

注意事項

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

命名空間和資料夾結構

數據提供者可以透過下列兩種方式之一來散發:

  1. 第三方附加元件
  2. Microsoft Mixed Reality 工具組的一部分

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

第三方附加元件

Namespace

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

  • 產生附加元件的公司名稱
  • 功能範圍

例如,Contoso 公司所建立並出貨的空間感知數據提供者可能是 “Contoso.MixedReality.Toolkit.SpatialAwareness”。

資料夾結構

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

範例資料夾結構

ContosoSpatialAwareness 資料夾包含資料提供者的實作時,編輯器資料夾包含偵測器 (和任何其他 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 工具組基礎提供下列空間物件,可在新的數據提供者中使用或擴充。

實作數據提供者

指定介面和/或基類繼承

所有空間感知數據提供者都必須實作 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 工具組中,會使用配置檔來設定數據提供者。

定義配置檔

配置文件內容應鏡像數據提供者的可存取屬性 (例如:更新間隔) 。 每個介面中定義的所有用戶可設定屬性都應該包含在配置檔中。

如果新的數據提供者擴充現有的提供者,則建議使用基類。 例如, 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 工具組會使用 .asmdef () 檔案的元件定義來指定元件之間的相依性,以及協助 Unity 縮短編譯時間。

建議為所有數據提供者及其編輯器元件建立元件定義檔案。

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

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

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

  • Microsoft.MixedReality.Toolkit
  • Microsoft.MixedReality.Toolkit。編輯器。督察
  • Microsoft.MixedReality.Toolkit。編輯器。公用事業

註冊數據提供者

建立之後,數據提供者就可以向空間感知系統註冊,以在應用程式中使用。

選取空間物件網格觀察者

封裝和散發

以第三方元件散發的數據提供者,會將封裝和散發的特定詳細數據保留在開發人員的喜好設定之下。 最常見的解決方案可能是產生 .unitypackage 並透過 Unity 資產存放區散發。

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

另請參閱