(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]


本ブログの運営者kan.kikuchiが個人で開発したゲームです!

    

障害物を避けながら目的地までの経路を自動で探索する【Unity】【NavMesh】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 2017.4.5f1


はじめに

今回はキャラクターを目的地まで自動で移動させたい!でも途中にある障害物は避けてほしい!

みたい事な時に使える、ナビゲーションシステム(NavMesh)の話です。

イメージとしては以下のような感じ。(青い床が通れる場所 : NavMesh)


f:id:kan_kikuchi:20180707053910g:plain


ナビゲーションシステム(NavMesh)とは

そもそもナビゲーションシステムとはなんぞや?という話からですが、

公式のマニュアルによると以下の通り。

ナビゲーションシステム(Navigation System)は、ゲーム世界をナビゲートする(動き回る)キャラクターの作成を可能にするものです。このシステムによって、二階へ行くためには階段を使用し、溝を越えるためにはジャンプしたりしなければならないことをキャラクターに理解させるすることができます。


名前の通り、キャラクターの動きをナビする仕組みで、

そのキャラクターが動ける場所を指定するメッシュをNavMeshと言います。


NavMesh作成

まず、Window -> Navigationでウィンドウを開きます。


f:id:kan_kikuchi:20180704121331j:plain
f:id:kan_kikuchi:20180704121344j:plain


デフォルトで各種設定がされてしまっているので、一旦リセットした方が分かりやすいです。

リセットするにはObjectタブのMesh Renderesを選び、

全オブジェクトを選択し、Navigation Staticを外します。


f:id:kan_kikuchi:20180707061847j:plain


リセットが済んだら歩ける場所のオブジェクト(今回はNaviMeshFloor)を選択し、

Navigation Staticにチェックを入れ、Navigation AreaをWalkableにします。


f:id:kan_kikuchi:20180704134523j:plain


次に障害物、つまり歩けない場所のオブジェクト(今回はBed)を選択し、

Navigation Staticにチェックを入れ、Navigation AreaをNot Walkableにします。


f:id:kan_kikuchi:20180704134627j:plain


なお、NavMeshを作成するためだけのオブジェクトを作成し、実際のゲームでは使わない

というやり方も可能です。(NavMeshを作成する時に表示、ゲーム中は非表示)


f:id:kan_kikuchi:20180704134919j:plain


オブジェクトの設定が済んだら次はBake(NavMeshの生成)の設定です。

各設定値はとりあえずデフォルトのままで大丈夫です。(設定値の説明はこちら)

f:id:kan_kikuchi:20180704134718j:plain


Bakeするとシーンに青いメッシュ(NavMesh)が生成されます。


f:id:kan_kikuchi:20180704134733j:plain


なお、このメッシュはシーンと同名のフォルダに生成されています。


f:id:kan_kikuchi:20180704134818j:plain


NavMeshAgent

NavMesh上を移動させたいキャラクターにはNavMeshAgentを使います。


f:id:kan_kikuchi:20180704142228j:plain


なんとNavMeshAgentのdestinationに位置を設定するだけで障害物を避けて自動で移動してくれます。

例えばキューブに向かって移動させたい場合は、Updateでキューブの位置を設定し続けるだけ。

//キューブのTransform(Inspector上でアタッチ)
[SerializeField]
private Transform _cube;

//NavMeshAgent(Inspector上でアタッチ)
[SerializeField]
private NavMeshAgent _navMeshAgent = null;

private void Update () {
  _navMeshAgent.destination = _cube.position;
}

f:id:kan_kikuchi:20180704144105g:plain


なお、NavMeshAgentのパラメータや各種関数は以下を参照の事。





おわりに

以上の通り、静的なNavMeshを作成して、そこの中で自動移動させるだけならかなり簡単でした!

とは言え、衝突判定の問題やメッシュの結合、オフメッシュリンクの活用等、

まだまだNavMeshに関連する話があるので、そこら辺もそのうち記事にするかもしれません。