テラシュールブログスマートフォン用の表示で見るテラシュールブログ旧テラシュールウェアブログUnity記事。UnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。AI今回は動的にNavMeshをベイクするNavMeshSurfaceについてです。APIのような物が公開され、NavMeshを動的にベイクすることが可能になりました。正確には、動的なベイク、及びベイクしたデータをアセットとして追加ロードですね。動的にNavMeshをベイクすることが可能になった事で、ステージのちょっとした変更(例えば橋がかかる、部屋が移動する等)でもNavMeshを使用した経路探索が使用できるようになった訳です(単純にせき止めるだけならNavmeshObstacleでも可能でしたが)で、今回は高レベルのコンポーネントのNavMeshComponentsの一つ、NavMeshSurfaceを使用した動的なNavMeshのベイクをやってみます。高レベルのコンポーネントを入手する高レベルのコンポーネントはGithubにて公開されています。このコンポーネントはNavMeshComponentsから入手できる他、NavMeshウィンドウのBakeにURLがあるので、そちらからも入手できます。入手出来るというか、Githubのページにジャンプするので、そこからCloneもしくはDownloadする感じです。ダウンロードしたコンポーネントの内、必要な項目はGizmosとNavMeshComponentsです。二つともプロジェクト内にインポートします。NavMeshComponentsは兎も角GizmosはAssets直下に配置する必要があります。NavMeshSurfaceを利用した動的なNavMeshのベイクNavMeshSurfaceを利用した動的なNavMeshのベイクをやってみます。この手順を利用する場合、殆どNavMeshウィンドウのBakeとObjectは使用しなくなります。このあたりの設定はコンポーネント側で行うためです。AgentsとAreasは相変わらず使用します。使ってみる実際の使用手順です。いっても難しい事はありません。最小限の方法は、NavMeshSurfaceコンポーネントのセットされているオブジェクトをシーン内に配置NavMeshAgentがパス計算を始める前にNavMeshSurface.Bakeを呼び出すこれだけです。SurfaceのセットまずNavMeshSurfaceのセット。SurfaceのNavMesh生成に使用するジオメトリはRendererとColliderの二種類なので、どちらかを選択します。NavMeshSurface.Bakeの呼出あとはNavMeshSurface.Bakeを呼び出すだけです。NavMeshAgent.SetDestinationを呼び出す他のコンポーネントより先に呼び出して欲しいので、DefaultExecutionOrderで実行順番を-102とか非常に前列に配置しています。gist.github.comDefaultExecutionOrderについてはコチラ。基本的には上の方法で利用可能ですが、それでは不十分なケースも多々あります。ベイクの範囲調整とか、エッジ調整とか、その辺り。ベイクの範囲を調整ベイクの範囲を制限したいケースがあります。ベイクにかかる時間を減らしたいようなケースです。広大な範囲をベイクするのは時間がかかるので、その辺りをコンパクトに抑えたいという話です。計算を実行時に行うのでこの辺りは特に。ベイクの範囲ですが、二つの方法があります。ベイク対象の範囲を限定するベイク対象をNavMeshSurfaceの子に限定するベイクの対象範囲を制限する方法では、NavMeshSurfaceを中心としてベイクの範囲を枠で囲った範囲に制限します。ベイクの範囲を限定出来るのでベイク速度は向上しますが、枠の範囲外にいるエージェントは動作しなくなるかもしれません。(もしくは範囲内に強制移動)このアプローチを見た後は、複雑な地形を複数のNavMeshSurfaceで簡略化しようと思うかもしれません。その場合、NavMeshは他のNavMeshに渡れない点に注意する必要があります。要するにNavMesh間移動にNavMeshLinkが必要です。3つ目の方法は、NavMeshSurfaceオブジェクトの子に配置したメッシュに対してベイクする...というものです。ステージが親子構造になっている場合、親にNavMeshSurfaceを配置するだけで良いので簡単です。ベイク対象から外すさて、NavMeshSurface側でベイクを行う訳ですが、例外的にコレを外したい...といった場合があります。具体的には範囲内にColliderかRendererを持つユニットが存在する場合、プレイヤーキャラの周辺にNavMeshがベイクされず穴が開く...みたいな事が起こります。この対策として四つのアイディアがあります。ビルド時には非アクティブにするレイヤーはベイクの対象となるレイヤーを制限するだけです。このアプローチでは、広い範囲で細かいレイヤー制御が期待出来ます。Unityのレイヤー数は何故か未だに31(しかもレンダリングとコライダーの判定が独立していない!)ので、この項目にレイヤーを使うのは出来れば避けたい所です。開発後半でレイヤーが足りなくなると悲惨です。WalkableやJump等)を加えることのできるコンポーネントです。Buildオプションを追加すると、ビルド対象から外してくれます。あとは単純にNavMeshSurfaceが子を収集してる場合は子から外してしまえばビルド対象外になりますし、ビルドする際にオブジェクトが無ければビルドに含まれません。エッジの調整NavMeshのエッジの調整です。Size)は大きければ大きいほど大雑把にNavMeshが構築されます。この設定が大きいと細い道が潰れて通れなくなったりします。逆に小さければ小さいほど、経路探索やベイクに時間がかかります(範囲によってはPCですら数十秒!)通常のNavMeshではこの項目はNavMeshウィンドウのBakeでやってきたのですが、NavMeshSurfaceはコンポーネント側に移動しています。設定する方法は二通り。TypeはNavMeshのエージェントのタイプを指定します。この項目はNavigationウィンドウで設定を作成し、各NavMeshAgent毎に設定する項目です。エージェントの幅や高さ、登れるステップの高さや登れる坂の角度等を指定します。要するに今までBakeで設定していたような項目です。Typeを作ってNavMeshSurfaceでその項目を指定すれば良いです。大きいNavMeshAgentには粗い(細かい所を移動出来ないNavMesh)が、小さいNavMeshAgentには細かい(細かい所が移動可能なNavMesh)が生成されます。NavMeshSurfaceは一つのNavMeshにつき一つのAgentTypeを指定できて、かつ範囲が重複しても問題無いので、トム&ジェリーのように、大きいエージェントだけが通れない道...みたいな事も出来ます。異なるAgentTypeのNavMeshは使えない点に注意。5.6のNavmeshで、「小さいユニティちゃんは小さい穴を通れる。大きなユニティちゃんは小さい穴が通れないので大きな穴を通る」をする。Typeの設定でさらに微調整したいような場合に使います。Obstacle用の判定です。こちらは再パス計算よりも高速ですが、再パス計算しないので通れなくなっても再パス計算を行いません。歩きスマホしてる人と同じような動きをします。関連キャラクターの周辺のみNavMeshを作る(動的に)みたいな場合は、NavMeshBuilderを使用したコチラの方法が良いです。2017のスライドです。NavMeshをベイク...2016-12-01【Unity】NavmeshAgaentの移動がOffMeshLink上で妙に加速するのを防ぐOffMeshLinkは複数のNavMeshを繋ぐ上で役に立つ機能です。...2016-11-29【Unity】Navmeshで障害物を避けて移動するルートを事前に取得する今回は経路探索AI(Navmesh)のルートだけを取得してみます。(1)月別アーカイブはてなブログをはじめよう!tsubaki_t1さんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。