MRが楽しい

MRやVRについて学習したことを書き残す

MRTKでスクリプトからSpatialAwarenessの表示設定を切り替える

本日は MRTK の小ネタ枠です。
MRTKでスクリプトからSpatialAwarenessの表示設定を切り替える方法を記事にします。

SpatialAwarenessの表示設定

SpatialAwareness の表示設定をスクリプトから操作するには SpatialAwarenessMeshObserver の DisplayOption にアクセスします。
microsoft.github.io

サンプルプロジェクトの作成

以下の記事に従って MRTK をインポートしたサンプルプロジェクトを作成します。
bluebirdofoz.hatenablog.com
f:id:bluebirdofoz:20210216235012j:plain

実装例

SpatialAwareness の表示設定を[表示(Vis][オクルージョン(Occlusion)][非表示(None)]に切り替える関数を持った以下のスクリプトを作成しました。
・SpatialAwarenessDisplaySwitch.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using Microsoft.MixedReality.Toolkit;
using Microsoft.MixedReality.Toolkit.SpatialAwareness;

public class SpatialAwarenessDisplaySwitch : MonoBehaviour
{
    public void SwitchVisible()
    {
        // 利用可能な最初のメッシュオブザーバーを取得する
        var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();

        // 表示(Visible)に設定する
        observer.DisplayOption = SpatialAwarenessMeshDisplayOptions.Visible;
    }

    public void SwitchOcclusion()
    {
        // 利用可能な最初のメッシュオブザーバーを取得する
        var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();

        // オクルージョン(Occlusion)に設定する
        observer.DisplayOption = SpatialAwarenessMeshDisplayOptions.Occlusion;
    }

    public void SwitchNone()
    {
        // 利用可能な最初のメッシュオブザーバーを取得する
        var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();

        // 非表示(None)に設定する
        observer.DisplayOption = SpatialAwarenessMeshDisplayOptions.None;
    }
}

f:id:bluebirdofoz:20210216235000j:plain

作成したスクリプトを適当なオブジェクトにアタッチします。
f:id:bluebirdofoz:20210216235022j:plain

後はシーン内で関数を呼び出すため、ボタンを配置してイベントに各関数を割り当てます。
f:id:bluebirdofoz:20210216235031j:plain

HoloLens2上での動作確認

アプリケーションをビルドして HoloLens2 にデプロイします。
ボタン操作で SpatialAwareness の表示を切り替えることができれば成功です。
f:id:bluebirdofoz:20210216235041j:plain
f:id:bluebirdofoz:20210216235053j:plain

エディター上での切り替え

以下の手順でディター上に仮想メッシュを表示しており、この仮想メッシュの表示タイプを切り替えて確認したい場合についてです。
この場合はメッシュオブザーバーが複数登録されているため、エディター上で動作させるにはスクリプトを修正する必要があります。
bluebirdofoz.hatenablog.com
f:id:bluebirdofoz:20210216235113j:plain

以下の通り、エディターでの動作時には追加した「Spatial Object Mesh Observer」のメッシュオブザーバを参照するようにコードを修正します。
・SpatialAwarenessDisplaySwitch.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using Microsoft.MixedReality.Toolkit;
using Microsoft.MixedReality.Toolkit.SpatialAwareness;

public class SpatialAwarenessDisplaySwitch : MonoBehaviour
{
    public void SwitchVisible()
    {
        // 利用可能な最初のメッシュオブザーバーを取得する
        var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
#if UNITY_EDITOR
        // エディター起動時は「Spatial Object Mesh Observer」のメッシュオブザーバを取得します
        var meshObserverName = "Spatial Object Mesh Observer";
        observer = ((IMixedRealityDataProviderAccess)CoreServices.SpatialAwarenessSystem).GetDataProvider<IMixedRealitySpatialAwarenessMeshObserver>(meshObserverName);
#endif

        // 表示(Visible)に設定する
        observer.DisplayOption = SpatialAwarenessMeshDisplayOptions.Visible;
    }

    public void SwitchOcclusion()
    {
        // 利用可能な最初のメッシュオブザーバーを取得する
        var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
#if UNITY_EDITOR
        // エディター起動時は「Spatial Object Mesh Observer」のメッシュオブザーバを取得します
        var meshObserverName = "Spatial Object Mesh Observer";
        observer = ((IMixedRealityDataProviderAccess)CoreServices.SpatialAwarenessSystem).GetDataProvider<IMixedRealitySpatialAwarenessMeshObserver>(meshObserverName);
#endif

        // オクルージョン(Occlusion)に設定する
        observer.DisplayOption = SpatialAwarenessMeshDisplayOptions.Occlusion;
    }

    public void SwitchNone()
    {
        // 利用可能な最初のメッシュオブザーバーを取得する
        var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
#if UNITY_EDITOR
        // エディター起動時は「Spatial Object Mesh Observer」のメッシュオブザーバを取得します
        var meshObserverName = "Spatial Object Mesh Observer";
        observer = ((IMixedRealityDataProviderAccess)CoreServices.SpatialAwarenessSystem).GetDataProvider<IMixedRealitySpatialAwarenessMeshObserver>(meshObserverName);
#endif

        // 非表示(None)に設定する
        observer.DisplayOption = SpatialAwarenessMeshDisplayOptions.None;
    }
}

f:id:bluebirdofoz:20210216235210j:plain

これでエディター上でも SpatialAwareness の切り替えを確認できるようになります。
f:id:bluebirdofoz:20210216235220j:plain
f:id:bluebirdofoz:20210216235229j:plain

ただしオクルージョン(Occlusion)の設定時にはクリアフラグの問題が発生するためか残像のようなものが見えてしまいます。
f:id:bluebirdofoz:20210216235238j:plain