MRが楽しい

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

SpatialMappingのデータにNavMeshを適用する その2

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

本記事は以下の記事を参考に作業を実施します。
tarukosu.hatenablog.com

「SDユニティちゃんを歩かせてみる」の項目からの実施になります。
まずは利用規約を確認し、以下のSDユニティちゃんデータを取得します。
・SDユニティちゃん 3Dモデルデータ
 http://unity-chan.com/download/releaseNote.php?id=SDUnityChan

前回作成したプロジェクトを改めて開きます。
ダウンロードした SD_UnityChan パッケージをプロジェクトに取り込みます。
f:id:bluebirdofoz:20170810023709j:plain

Assets/UnityChan/SD_unitychan/Prefabs 配下から SD_unitychan_humanoid.prefab をシーンに追加します。
f:id:bluebirdofoz:20170810023718j:plain

次に SD_unitychan_humanoiod オブジェクトのコンポーネントを以下の通り、設定します。
1.調整した Agent の大きさに合うようスケールを全て 0.3 に設定する。
2.SD_unitychan_humanoid にアタッチされている Script について全て無効化する。
3.NavMeshAgent のコンポーネントをアタッチする。
f:id:bluebirdofoz:20170810023727j:plain
NavMeshAgent の Speed や Obstacle は参考記事を元に値を調整しています。
Agent の希望する移動速度やモデルの大きさに合わせて設定するようです。

次に SD_unitychan_humanoid の移動モーションを設定します。参考記事にある通り、下記を参照します。
tsubakit1.hateblo.jp

最初に Animator コンポーネントにある ApplyRootMotion のチェックを外します。
f:id:bluebirdofoz:20170810023750j:plain
これでキャラクタの移動は NavMeshAgent または Scriptでしか動かなくなります。

Assets で右クリック -> Create -> AnimatorController で新しいアニメーションコントローラを作成します。
f:id:bluebirdofoz:20170810023801j:plain

作成した Animator を開いたら Float 型の Speed パラメータを追加します。
f:id:bluebirdofoz:20170810023811j:plain

モーションの設定として「ブレンドツリー」の機能を使います。
Animator ビュー上で右クリック -> CreateState -> FromNewBlendTree で「ブレンドツリー」の State が作成できます。
f:id:bluebirdofoz:20170810023821j:plain

作成された BlendTree を選択し、Motion に設定されている BlendTree をダブルクリックします。
f:id:bluebirdofoz:20170810023831j:plain

すると BlendTree の Inspector タブが表示されます。
まず Motion の「+」ボタンを押下して AddMotionField を選択し、3つのモーションを追加します。
f:id:bluebirdofoz:20170810023842j:plain

次に AutomateThresholds のチェックを外します。
すると、閾値の設定が手動で行えるようになるので、Motion と Threshold を以下の通り設定します。
f:id:bluebirdofoz:20170810023853j:plain
ちなみにモーション選択の際、SDユニティちゃんをそのままインポートしていると、それぞれ同名の2種類のモーションがあります。
このとき、~_humanoid というファイル名になっている方のモーションを選択するようにします。

以上でアニメーションコントローラの作成は完了です。
SD_unitychan_humanoid オブジェクトの Animator にコントローラを設定します。
f:id:bluebirdofoz:20170810023905j:plain

移動中に Speed パラメータを操作してモーションを再生するスクリプトを用意します。
参考記事の unitychanAnimation.cs スクリプトを作成し、SD_unitychan_humanoid オブジェクトに追加します。
f:id:bluebirdofoz:20170810023915j:plain

最後にタップ位置まで移動するスクリプトを用意します。
以下の手順で MoveToClickPoint オブジェクトを作成します。
1.空オブジェクトの MoveToClickPoint オブジェクトを作成する。
2.参考記事の MoveToClickPoint.cs スクリプトを作成し、MoveToClickPoint オブジェクトに追加する。
3.MoveToClickPoint.cs スクリプトの Agent に SD_unitychan_humanoid オブジェクトを設定する。
4.MoveToClickPoint オブジェクトに LineRenderer コンポーネントを追加する。
f:id:bluebirdofoz:20170810023924j:plain

unity 上で動作確認を行うため、MoveToClickPoint.cs について以下のコードを追加しました。
・MoveToClickPoint.cs

  void Update()
  {
    if (Input.anyKeyDown)
    {
      Debug.Log("click LOG");
      if (GazeManager.Instance.IsGazingAtObject)
      {
        var hitInfo = GazeManager.Instance.HitInfo;
        if (!Agent.gameObject.activeSelf)
        {
          Agent.gameObject.SetActive(true);
          Agent.transform.position = hitInfo.point;
        }
        else
        {
          Agent.destination = hitInfo.point;

          // パスの計算
          var path = new NavMeshPath();
          NavMesh.CalculatePath(Agent.transform.position, Agent.destination, NavMesh.AllAreas, path);
          var positions = path.corners;

          // ルートの描画
          lineRenderer.widthMultiplier = 0.1f;
          lineRenderer.positionCount = positions.Length;
          for (int i = 0; i < positions.Length; i++)
          {
            Debug.Log("point " + i + "=" + positions[i]);
            lineRenderer.SetPosition(i, positions[i]);
          }
        }
      }
    }
  }

シーンを再生して、移動先に視点を合わせてマウスクリックを行うと……。
f:id:bluebirdofoz:20170810023937j:plain
SDユニティちゃんが NavMesh の移動可能範囲に沿ってルートを自動生成して歩きました。成功です。
こんなに簡単に動的な経路探索のロジックが利用できるとは驚きです。

次回は経路探索のロジックを応用して、現在位置から目的地の道筋を表示する機能を試してみます。
bluebirdofoz.hatenablog.com