【HoloLens2 MRTK】SceneUnderstandingで設定したオブジェクト作られる際のイベント取得

## まず、MRTKのSceneUnderstaindingとは…
* 参考
    * https://qiita.com/Futo_Horio/items/2759f9ca2b892709ab66
    * https://redhologerbera.hatenablog.com/entry/2020/12/28/232605
* 床や壁などを識別して簡略化したグラフィックを配置できる（しなくてもよい）

そのSceneUnderstandingでは検出の更新頻度や生成するオブジェクトを設定できます

[![Image from Gyazo](https://i.gyazo.com/6023df39209f0a143efd800e7be6440b.png)](https://gyazo.com/6023df39209f0a143efd800e7be6440b)

画像では壁のみ、5秒間隔で更新し、オブジェクトを生成させるような設定をしています

## 環境
* Unity v2019.4.18
* MRTK v2.7.2
* SceneUnderstanding v0.6.0

## オブジェクト追加イベント取得するコード

```C#
using Microsoft.MixedReality.Toolkit.Examples.Demos;
using Microsoft.MixedReality.Toolkit.Experimental.SpatialAwareness;
using Microsoft.MixedReality.Toolkit.SpatialAwareness;
using UnityEngine;

public class SceneUnderstandingController : DemoSpatialMeshHandler, IMixedRealitySpatialAwarenessObservationHandler<SpatialAwarenessSceneObject>
{
    protected override void Start()
    {
    }

     protected override void OnEnable()
    {
        RegisterEventHandlers<IMixedRealitySpatialAwarenessObservationHandler<SpatialAwarenessSceneObject>, SpatialAwarenessSceneObject>();
    }

    protected override void OnDisable()
    {
        UnregisterEventHandlers<IMixedRealitySpatialAwarenessObservationHandler<SpatialAwarenessSceneObject>, SpatialAwarenessSceneObject>();
    }

    protected override void OnDestroy()
    {
        UnregisterEventHandlers<IMixedRealitySpatialAwarenessObservationHandler<SpatialAwarenessSceneObject>, SpatialAwarenessSceneObject>();
    }

    public void OnObservationAdded(MixedRealitySpatialAwarenessEventData<SpatialAwarenessSceneObject> eventData)
    {
        Debug.Log("added!!");
        Debug.Log(eventData);
    }

    public void OnObservationUpdated(MixedRealitySpatialAwarenessEventData<SpatialAwarenessSceneObject> eventData)
    {
    }

    public void OnObservationRemoved(MixedRealitySpatialAwarenessEventData<SpatialAwarenessSceneObject> eventData)
    {
        Debug.Log("removed!!");
        Debug.Log(eventData);
    }

}

```

`DemoSpatialMeshHandler` はMRTKのExampleを入れて、PackageManagerからSpatialAwarenessを追加したら使えた

[![Image from Gyazo](https://i.gyazo.com/163d06301f79bd0f25d59df082d336e8.png)](https://gyazo.com/163d06301f79bd0f25d59df082d336e8)

一応コードも張っておきます

```C#:DemoSpatialMeshHandler
#region アセンブリ Microsoft.MixedReality.Toolkit.Examples, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// C:\Users\Honeycomb-lab\Documents\ono\LIXIL_holo2\LIXLI_holo2\Library\ScriptAssemblies\Microsoft.MixedReality.Toolkit.Examples.dll
#endregion

using Microsoft.MixedReality.Toolkit.SpatialAwareness;
using UnityEngine;
using UnityEngine.EventSystems;

namespace Microsoft.MixedReality.Toolkit.Examples.Demos
{
    [AddComponentMenu("Scripts/MRTK/Examples/DemoSpatialMeshHandler")]
    public class DemoSpatialMeshHandler : MonoBehaviour, IMixedRealitySpatialAwarenessObservationHandler<SpatialAwarenessMeshObject>, IEventSystemHandler
    {
        protected bool isRegistered;

        public DemoSpatialMeshHandler();

        public virtual void OnObservationAdded(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData);
        public virtual void OnObservationRemoved(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData);
        public virtual void OnObservationUpdated(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData);
        protected void AddToData(int eventDataId);
        protected virtual void OnDestroy();
        protected virtual void OnDisable();
        protected virtual void OnEnable();
        protected virtual void RegisterEventHandlers<T, U>()
            where T : IMixedRealitySpatialAwarenessObservationHandler<U>
            where U : BaseSpatialAwarenessObject;
        protected void RemoveFromData(int eventDataId);
        protected virtual void Start();
        protected virtual void UnregisterEventHandlers<T, U>()
            where T : IMixedRealitySpatialAwarenessObservationHandler<U>
            where U : BaseSpatialAwarenessObject;
        protected void UpdateData(int eventDataId);
    }
}
```

これで見てみると5秒間隔で `OnObservationRemoved` が検出した壁や床の数分だけ実行されて、直後に `OnObservationAdded` が実行される感じ

なので、実は壁や床のオブジェクトが点滅するような見た目になっちゃっています

[![Image from Gyazo](https://i.gyazo.com/c99c14cd971181912aeeca73d02a7070.gif)](https://gyazo.com/c99c14cd971181912aeeca73d02a7070)

解決方法は現在執筆中…

## 【いったんの追記】

点滅するような見た目の解決策として、いったん

`Update Interval` の直上の `Auto Update` のチェックを外しておくとよさそうです

Updateを明示的にスクリプトから読み込むか、表示するときの最初一回だけでもかなり精度いい気がします。

また、Holo2は過去に取得した情報を保持しているっぽいので、結構使っている空間であればUpdateなくても違う部屋の情報なんかもすでにあったりします。