LoginSignup
1
1

More than 3 years have passed since last update.

RecastNavigationを使ってナビゲーションAIを学習していく 5

Last updated at Posted at 2021-02-24

初めに

 この記事はOffMesh Linkの自動生成の後半です。見ていない人は前半の記事を見て下さい。

目次

以降は予定です。1

  • 第2回:移動エリアの可・不可・コストの設定
  • 第3回:複数のメッシュによるナビメッシュ生成
  • 第4回:動的なナビメッシュ生成

方法

4. 決定した仮リンクに調整・修正する

 さて...ここまでくれば、煮るなり焼くなり自由です。仮リンクはこれ以上は増えないので、後はユーザー定義で色々なオプションを付けたりする事で更なる改造・削除が可能になります。とりあえず、今回は

  • 仮リンクの被りチェック
  • 「横跳び」の有無の設定

の設定をしようと思います。

仮リンクの被りチェック

仮リンク 被り.png
 このように、自動生成した際にどうしても被る可能性があるのでその仮リンクの削除を行います。更に、双方向通行に設定しなければなりません。
仮リンク 被り解消.png
この項目は仮リンクが無駄に多く密集してしまうのを防ぐ為に必須です。

  • 青矢印:仮リンク
  • 紫丸 :垂直上のポイント
  • 緑線 :ナビメッシュ
  • 白丸 :分割点

 ここで、前回の最後に書いた「垂直ベクトルを構築する際に「高さ」を考慮する」についての補足をしておきます。上記のように「高さ」を考慮すると今まで「一方通行」だったのが、「双方向通行」になる可能性があります。逆に「高さ」を考慮していないと、「一方通行で登る事が出来ない」や「構築時のレイに当たらず、地形を通り越して構築される」のような事態が発生します。
垂直ベクトルの高さ2.png
 この場合だと下の地形側で構築する際に、上に地形があるにもかかわらず、ベクトルが貫通してしまい、結果「貫通」する事態に陥ります。なお、上下間の地形にはエージェントが通過できるほどの高さはありません。
垂直ベクトルの高さ3.png
 このように「高さ」を考慮する事で、下の地形側で構築する際に「貫通」はしません。

  • 青矢印  :垂直ベクトル
  • 黄緑矢印 :直下ベクトル
  • 黄丸   :水平上のポイント
  • 紫丸   :垂直上のポイント
  • 白丸   :分割点
  • 緑線   :ナビメッシュ
  • 赤線   :垂直ベクトルを構築する時の高さ

上記の仮リンク構築の結果としては下図になります。
垂直ベクトルの高さ4.png

「横跳び」の有無の設定

 この「横跳びの有無」というのは「仮リンクの始点~終点間の高さが指定範囲以内の仮リンクを構築可能にするかどうか」という事です。つまり、水平方向に仮リンクを構築出来ないようにします。ただ、必要な場合もあるので、構築時にフラグで切り替えできるようにしておきます。
横跳び.png

  • 青矢印:仮リンクを構築可
  • 茶矢印:仮リンクを構築不可
  • 紫丸 :垂直上のポイント
  • 緑線 :ナビメッシュ
  • 白丸 :分割点

5. OffMesh Linkを作成する

 さて、あとは実際に構築するだけです。
自動構築完了1.png
 ただし、ここで注意しなければならない点は「既に自動構築されたOffMesh Linkは削除しなければならない」事です。でないと、何重にもOffMesh Linkが構築されてしまいます。
 実際に構築するのは任意のタイミングでも構わないと思います。正直、お試しで何度も実際に構築するのは、プログラマーとしては気に入りません。その為の「仮リンク」なので...。
2021-02-08_04-14-33-1-3
※ 試しに群衆エージェントを動かしている図です。

調整

 実はこれだけでは自動作成自体はいけるのですが、「仮リンクが地形にめり込む」「余計な仮リンクが作成される」「Temp Obstacleを貫通して仮リンクが作成される」などが発生します。なので、その修正を行います。

例1 Temp Obstacleを貫通

 Temp Obstacleとの判定は行っていないので、ここで削除するようにします。
Temp Obstacleを貫通1.png

例2 双方向通行にならない

これは現状2パターンが存在します。

1. 優先順位の関係で不可

 これは、終点を探す過程で手前側から検索している為に発生します。先に下の方にあるナビメッシュにレイが当たり、一方通行になっている状態です。これを解決するには仮リンクの始点・終点で別途確認しなければなりません。
双方向通行にならない-パターン1-1.png
双方向通行にならない-パターン1-2.png

2. 開始地点が存在しない

 これは、一見正常なのですが、空中に浮いているような地形に「ジャンプ」や「崖つかまり」などの場合に必要になります。というのも、仮リンクの終点がナビメッシュのエッジ近くに存在せず、例え登れる高さだとしても、「始点」が無い事には仮リンクを作成する事が不可能だからです。これも、仮リンクの始点・終点で別途確認しなければなりません。
双方向通行にならない-パターン2-1.png
双方向通行にならない-パターン2-2.png

  • 青矢印  :垂直ベクトル
  • 黄緑矢印 :直下ベクトル
  • 黄丸   :水平上のポイント
  • 紫丸   :垂直上のポイント
  • 白丸   :分割点
  • 緑線   :ナビメッシュ
  • 赤点線  :垂直ベクトルを構築する時の高さ

例3 余計な仮リンクが生成される

余計なリンク.png
 例えば上図のようなリンクが発生します。このリンクは始点・終点付近のナビメッシュエッジが向き合っておらず、始点のナビメッシュエッジに対し、終点のナビメッシュエッジが90°近くずれている為です。なのでナビメッシュエッジ角度に制限を設定します。

追加実装&修正

 これだけでも、出来ているといえば出来ているのですが、人間は欲深いものです。あれやこれやと「追加しろ~」と言われるのは目に見えています。なので、以降は「プラスα」として実装します。

自動構築不可エリアの設定

 自動生成で生成出来るのはいいのですが、例えば「家の周囲」など、ある特定の部分を構築したくない場合もあるのでその設定を行います。簡易的なエリアなのでAABBで十分でしょう2
自動構築不可エリア.png

仮リンクが存在するタイルのナビメッシュを自動で再構築する

 これはどうしようもないのですが、OffMesh Linkが動的でないので、追加したらナビメッシュを再生成する必要があります。なので、OffMesh Link付近に存在するタイルのナビメッシュを自動生成するようにします。これを行わないと変更するたびに全てのナビメッシュを再構築しなければなりません。
付近のタイルのナビメッシュを自動生成.png
 この赤のタイルのみ再生成します。少しでもナビメッシュの再構築時間を短くする狙いです。

最後に

 これで、一旦終わりになります。追加で色々するかもしれませんが、落ち着いてからになると思います。次回は先に「複数のメッシュによるナビメッシュ生成」をしようと思います。


  1. 近日中に上げたいと思います。※順番は前後する可能性があります。 

  2. OBBだと計算が面倒くさいとは言ってはいけません。 

1
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1