MRが楽しい

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

MRTK2.5でNavMeshComponentsを使って動的経路探索を試す その2

本日は MRTK と NavMesh の技術調査枠です。
MRTK2.5でNavMeshComponentsを使って動的経路探索を試す手順を記事にします。
f:id:bluebirdofoz:20210208231405j:plain

本記事は経路探索の結果をHoloLens上で表示して確認します。

前提条件

前回記事の続きです。
bluebirdofoz.hatenablog.com

目的地を設定する

最初に HoloLens 上でタップ操作で目的地を設定できるようにします。
目的地を示すオブジェクトとして Goal オブジェクトを追加しました。
f:id:bluebirdofoz:20210208231420j:plain

SurfaceMagnetism を使ってタップした現実空間の位置に Goal オブジェクトを移動させます。
詳細な設定手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com
f:id:bluebirdofoz:20210208231437j:plain
f:id:bluebirdofoz:20210208231447j:plain
f:id:bluebirdofoz:20210208231458j:plain

これでタップ位置に Goal オブジェクトで目的地が設定できるようになります。
f:id:bluebirdofoz:20210208231509j:plain

経路表示用スクリプトを作成する

開始点から目的地までの経路探索結果を表示するスクリプトを作成します。
LineRenderer で経路を描画する以下のスクリプトを作成しました。
・LineNavigation.cs

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

public class LineNavigation : MonoBehaviour
{
    [SerializeField, Tooltip("開始位置オブジェクト")]
    private GameObject StartObject;

    [SerializeField, Tooltip("目的位置オブジェクト")]
    private GameObject GoalObject;

    NavMeshAgent Agent;
    LineRenderer PathLineRenderer;

    [SerializeField, Tooltip("ライン描画間隔(s)")]
    private float timeOut = 1.0f;
    private float timeElapsed;

    void Start()
    {
        // 各コンポーネントの参照を取得する
        PathLineRenderer = GetComponent<LineRenderer>();
        Agent = GetComponent<NavMeshAgent>();

        // Agentとオブジェクトの位置同期を無効化する
        Agent.speed = 0f;
        Agent.updatePosition = false;
    }

    void Update()
    {
        timeElapsed += Time.deltaTime;

        if (timeElapsed >= timeOut)
        {
            // 目的地を設定する
            Agent.destination = GoalObject.transform.position;
            // エージェントの位置をスタートオブジェクトの位置に同期する
            Agent.nextPosition = StartObject.transform.position;

            // 経路のパスを取得する
            Vector3[] positions = Agent.path.corners;

            // パスを取得できたか確認する
            if (positions.Length > 1)
            {
                // 経路のパスをラインレンダラーで描画する
                PathLineRenderer.positionCount = positions.Length;
                for (int i = 0; i < positions.Length; i++)
                {
                    Debug.Log("point " + i + "=" + positions[i]);
                    // ラインをパスの位置から50cm上げた位置に配置する
                    Vector3 linePos = new Vector3(positions[i].x, positions[i].y + 0.5f, positions[i].z);
                    PathLineRenderer.SetPosition(i, linePos);
                }
            }

            timeElapsed = 0.0f;
        }
    }
}

f:id:bluebirdofoz:20210208231523j:plain

新規オブジェクトを作成し、作成スクリプトが参照する[NavMeshAgent]と[LineRenderer]コンポーネントを追加します。
f:id:bluebirdofoz:20210208231533j:plain

更に作成した[LineNavigation]スクリプトを追加します。
f:id:bluebirdofoz:20210208231544j:plain

[LineNavigation]のプロパティを設定します。
開始点として[StartObject]には[Main Camera]を、目的地として[GoalObject]に[Goal]オブジェクトを指定します。
f:id:bluebirdofoz:20210208231555j:plain

最後にラインの見た目を[LineRenderer]のプロパティで変更します。
f:id:bluebirdofoz:20210208231605j:plain

エディター上の動作確認

エディター上でシーンを再生して動作を確認します。
自分の現在位置からタップした位置までの経路が表示されれば成功です。
f:id:bluebirdofoz:20210208231616j:plain

HoloLens上の動作確認

HoloLens にアプリケーションをインストールして確認します。
デフォルトでは SpatialAwareness は3m四方の範囲しか保持されないので、より広い範囲を経路探索する場合はプロファイルで範囲を変更しておきます。
f:id:bluebirdofoz:20210208231626j:plain

HoloLens 上で現実空間のスキャンに合わせて経路探索が行われれば成功です。
f:id:bluebirdofoz:20210208231634j:plain

参考ページ

tarukosu.hatenablog.com