本日は MRTK と NavMesh の技術調査枠です。
MRTK2.5でNavMeshComponentsを使って動的経路探索を試す手順を記事にします。
本記事は SpatialAwareness の動的経路探索です。
NavMeshComponents
NavMeshComponents は NavMesh を活用するための以下の4つのコンポーネントを提供します。
・NavMeshSurface
・NavMeshModifier
・NavMeshModifierVolume
・NavMeshLink
github.com
今回はこの NavMeshComponents を使って MRTK が構成する SpatialAwareness のメッシュに動的に NavMesh を適用します。
NavMeshComponentsの取得
以下のページから NavMeshComponents をダウンロードします。
今回は[DownloadZIP]から直接ダウンロードを行いました。
NavMeshComponents を取得する際にはエディターのバージョンに合わせたブランチを利用することが推奨されています。
今回はコードの一部のみの利用のため、master ブランチから取得しても問題ありませんでした。
Please use the branch matching the version of your Unity editor: master for the latest released LTS version and up to 2020.2, 2019.3 for up to 2019.4-LTS, 2018.3 for up to 2018.4-LTS and 2019.2, 2018.2, 2018.1, 2017.2 for up to 2017.4-LTS, 2017.1, 5.6. You can use the package branch in Unity 2019.4 or newer in order to add this code to a project in the form of a package. For instructions please refer to the Setup section of the README file.
ダウンロードしたファイルを展開します。
今回は以下の2つのスクリプトを利用します。
・Assets/Examples/Scripts/LocalNavMeshBuilder.cs
・Assets/Examples/Scripts/NavMeshSourceTag.cs
MRTKプロジェクトの作成
MRTK 2.5をインポートして基本設定を行ったサンプルプロジェクトを準備します。
今回はエディター上で動作確認を行いたいので、SpatialObjectMeshObserver で表示するメッシュを取り込みます。
SpatialObjectMeshObserver の設定手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com
取り込んだメッシュで SpatialAwareness が動作することを確認します。
取り込んだメッシュは NavMesh のアクセス対象となるため、読み込み/書き込み権限を与えておく必要があります。
3Dファイルの Inspector ビューを開き、[Read/Write Enabled]にチェックを入れておきます。
NavMeshComponentsの取り込み
SpatialAwareness のメッシュに NavMesh の経路探索を行うスクリプトを取り込みます。
初めに NavMeshComponents から先述の2つのスクリプトを取り込みます。
・Assets/Examples/Scripts/LocalNavMeshBuilder.cs
・Assets/Examples/Scripts/NavMeshSourceTag.cs
シーンに新規オブジェクトを作成し、LocalNavMeshBuilder コンポーネントを設定しておきます。
本コンポーネントで設定した範囲内で経路探索が行われます。
SpatialAwareness操作スクリプトの作成
SpatialAwareness に経路探索を行う NavMeshSourceTag コンポーネントを設定するスクリプトを作成します。
以下のようなスクリプトを作成しました。
・SpatialAwarenessNavMesh.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using Microsoft.MixedReality.Toolkit; using Microsoft.MixedReality.Toolkit.SpatialAwareness; namespace SpatialAwarenessNavMesh { using SpatialAwarenessHandler = IMixedRealitySpatialAwarenessObservationHandler<SpatialAwarenessMeshObject>; public class SpatialAwarenessNavMesh : MonoBehaviour, SpatialAwarenessHandler { /// <summary> /// Value indicating whether or not this script has registered for spatial awareness events. /// このスクリプトが SpatialAwareness イベントに登録されているかどうかを示す値。 /// </summary> private bool isRegistered = false; private void Start() { RegisterEventHandlers(); } private void OnEnable() { RegisterEventHandlers(); } private void OnDisable() { UnregisterEventHandlers(); } private void OnDestroy() { UnregisterEventHandlers(); } /// <summary> /// Registers for the spatial awareness system events. /// </summary> private void RegisterEventHandlers() { if (!isRegistered && (CoreServices.SpatialAwarenessSystem != null)) { CoreServices.SpatialAwarenessSystem.RegisterHandler<SpatialAwarenessHandler>(this); isRegistered = true; } } /// <summary> /// Unregisters from the spatial awareness system events. /// </summary> private void UnregisterEventHandlers() { if (isRegistered && (CoreServices.SpatialAwarenessSystem != null)) { CoreServices.SpatialAwarenessSystem.UnregisterHandler<SpatialAwarenessHandler>(this); isRegistered = false; } } /// <inheritdoc /> public virtual void OnObservationAdded(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData) { // Mesh追加時のイベント Debug.Log($"Tracking mesh {eventData.Id}"); // NavMeshSourceTag をオブジェクトに追加 eventData.SpatialObject.GameObject.AddComponent<NavMeshSourceTag>(); } /// <inheritdoc /> public virtual void OnObservationUpdated(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData) { // Mesh更新時のイベント Debug.Log($"Update mesh {eventData.Id}"); // NavMeshSourceTag をオブジェクトに追加 NavMeshSourceTag tag = eventData.SpatialObject.GameObject.GetComponent<NavMeshSourceTag>(); if (tag == null) { eventData.SpatialObject.GameObject.AddComponent<NavMeshSourceTag>(); } } /// <inheritdoc /> public virtual void OnObservationRemoved(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData) { // Mesh削除時のイベント Debug.Log($"Remove mesh {eventData.Id}"); } } }
作成したスクリプトをシーン内のオブジェクトに追加します。
NavMeshの設定
プロジェクトに NavMesh の設定を行います。
メニューから[Window -> AI -> Navigation]を選択します。
[Navigation]タグが追加され、[Scene]画面に[NavimeshDisplay]が表示されます。
[Show NavMesh]を有効化しておくと、シーン再生時に NavMesh の経路探索の結果を確認できます。
動作確認
シーンを再生します。
SpatialAwareness のメッシュに NavMesh の経路探索の結果が青いフィールドで表示されていれば成功です。
経路探索の設定変更
動的な経路探索の条件を変更する場合は[Navigation]ビューの[Agents]で設定を変更します。
試しに半径と段差の乗り降りの値を小さく設定してみます。
この状態でシーンを再生してみると、NavMesh の経路探索の結果が変わります。
小さな段差の上り下りが繋がらなくなっていることが分かります。
次は HoloLens2 上で動作を確認してみます。
bluebirdofoz.hatenablog.com