まずはこちらのデモをご覧ください。

現在、UIUXの研究を兼ねて作成中のMagicLeapのお絵描きアプリです。
ボタンを押してオクルージョンのオンオフが可能なように実装しています。
手にもオクルージョンをかけています。

MeshingというサンプルシーンがMagicLeapSDK内にありますが、
今回最低限の機能に絞って実装を行ったのでメモしておきます。


バージョン情報

Unity 2019.2.21f1
Lumin OS v0.98.10
Lumin SDK 0.24.1
OS Windows10


下準備

空間のオクルージョン

まずは空間のオクルージョンの処理の下準備です。
MLSpatialMapperというPrefabをHierarchyに配置します。


そして、Prefabを解除し、Scaleを(5,5,5)に変更します。
合わせて、Mesh Parentという空のオブジェクトを生成しアタッチします。

次にMLSpatialMapperの子のオブジェクトであるOriginal
下記画像のように設定します。

今回のように、
遮蔽物として使うだけであればMeshColliderは削除してしまって構いません。

MeshRendererに関してですが、
オクルージョンをオフの状態から始める実装の場合は
enableのチェックを外しておきます。


手のオクルージョン

手のオクルージョンに関してはHandMeshというPrefabを
Hierarchyに配置するだけです。

ちなみに手のオクルージョンに関してはEditor上で実機の検証が可能な
ZeroIterationには対応していない
ので、ビルドして検証するしかないです。


コード

まずは全文です。

using UnityEngine;
using UnityEngine.Experimental.XR;
using UnityEngine.XR.MagicLeap;

public class OcclusionFunction : MonoBehaviour
{
    [SerializeField] private MLSpatialMapper _mlSpatialMapper;
    [SerializeField] private Transform _meshParent;
    
    private bool isOcclusion;
    
    private void Start()
    {
        //メッシュが追加された際のコールバック登録
        _mlSpatialMapper.meshAdded += HandleOnMeshReady;
    }

    /// <summary>
    /// メッシュのIDから新しく生成したメッシュの設定を更新
    /// </summary>
    /// <param name="meshId">生成されたメッシュのID</param>
    private void HandleOnMeshReady(TrackableId meshId)
    {
        if (_mlSpatialMapper.meshIdToGameObjectMap.ContainsKey(meshId))
        {
            _mlSpatialMapper.meshIdToGameObjectMap[meshId].GetComponent<MeshRenderer>().enabled = isOcclusion;
        }
    }

    /// <summary>
    /// 認識したマップのメッシュを変更 Buttonの押下イベントにInspectorで登録
    /// </summary>
    public void OcclusionOnOff()
    {
        //既存の平面メッシュをオンオフ切り替え
        foreach (Transform child in _meshParent)
        {
            MeshRenderer childMesh = child.GetComponent<MeshRenderer>();

            childMesh.enabled = !isOcclusion;
        }

        
        isOcclusion = !isOcclusion;
        Debug.Log("Occlusion:" + isOcclusion);
    }
}

やっていることとしては非常にシンプルです。
OcclusionOnOffの中で生成されたメッシュ全てを
foreachで1つずつenableを切り替えてます。


meshAdded

空間のメッシュは認識でき次第、順次生成される仕組みになっているので
新しく生成されるPrefabの情報を切り替える必要があります。

そこで、MLSpatialMappermeshAddedというコールバックを利用します。
生成されるたびに、生成されたメッシュIDのオブジェクトを検索し
設定を更新しています。

最後に

今回は物理的な干渉は無いオクルージョンだけの平面を生成し利用しました。
MLSpatialMapperを利用すればMR空間上のオブジェクトを物理的に
現実空間とインタラクションさせることも可能です。