初めに

この記事は KLab Advent Calendar 14日目の記事です。

こんにちは、クライアントエンジニアの norm81 です。

初登場です、よろしくお願いします。  

経緯  

Unityでナビメッシュのベイク情報をプレハブにしたい、そしてアセットバンドルで運用したいという要望がありました。

既存のA*アセットなどを検証していたところ、Unity5.6からNavMeshBuilderが強化されたのでそちらで実現可能か検証しました。 

静的にベイクしたデータを用いたサイトをあまり見掛けなかったので今回纏めてみようと思います。  

検証に用いたUnityバージョンは5.6.3f1です。

結論

いきなり結論になりますが、上記の要望は対応できました。  

但し、制限があります。  

今回の方法において注意点も見つかりましたので、併せて下記に記載しています。  

導入

下記をクローンし、対象のプロジェクトに入れます。

https://github.com/Unity-Technologies/NavMeshComponents/

Assets/NavMeshComponents/フォルダをコピーしてねと書かれてますが、  

今回はAssets/Examples/フォルダも用います。  

手順

基本的には既存にあるナビメッシュの作成の通り、設定を行なっていきます。  

但し、Bakeは別途行うのでこのタイミングでは行いません。  

  

ヒエラルキーでナビメッシュの対象にするRendererコンポーネントを持つオブジェクトの親に、一つ空オブジェクトを作成します。  

そしてAssets/Examples/フォルダに入っているNavMeshPrefabInstanceコンポーネントをAddComponentします。  

01

そのオブジェクトを含むプレハブを保存した後にインスペクタのSelectボタンを押す、或いはプロジェクトウィンドウから保存したプレハブを選択すると、入れ子にあるオブジェクトが表示されます。

そのままNavMeshPrefabInstanceコンポーネントを持つオブジェクトを選択して、インスペクタのNavMeshPrefabInstanceコンポーネントのBakeボタンを押します。  

するとプレハブにNavMeshが追加されます。

確認 

Navigationウィンドウを開き、Show NavMeshを有効にした状態でWalkableのメッシュが表示されていれば成功です。

02

表示されていない場合、追加されたNavMeshを確認してみてください。Source BoundsのExtents値が(0, 0, 0)だと失敗している可能性が高いです。

03

下記の注意点を確認いただき、再度上記のBakeを試みてください。

成功した後は、このプレハブをアセットバンドルにすればそのまま運用可能です。

具体的な挙動については、上記NavMeshComponentsのソースコードを参考されることをオススメします。

注意点

NotWalkableを反映したナビメッシュがBakeできない。

従来のNavigationウィンドウでのBakeとは異なり、差集合のベイクがなされないです。  

対案としてMeshColliderを併用して目的座標に対して上空からのRayCastで判定を行い進入可能か調べる様なような二段構えの対応を検討しています。

FBXなどModelImporterを介するMeshを扱う場合、Bake前にRead/Write Enableを有効にする必要がある。  

04

プレハブに保存した後に無効に戻すのは問題なかったです。  

まとめ

現時点の外部データ化するメリットは、

  • ランタイムでベイクしなくて良いので処理コストが軽減できる。  
  • 1つの背景データと複数の外部データ化したナビメッシュを組み合わせることで、クエスト進行度などに併せてナビメッシュを切り替える運用ができる。  

といったところで、デメリットは注意点で記載したとおりになります。  

今回紹介した機能は折角の標準搭載された機能なので使い倒してみたいと思います。

以上