目的
Unity実行中にシーン内に存在するMeshFilterからNavMeshを動的に生成し、NavMeshAgentに経路探索させます
とにかくコードが見たい人はこちら
https://github.com/lisearcheleeds/SimpleNavMesh/tree/master/Assets/Scripts/SimpleNavMesh
動機
UnityではNavMeshという経路探索AIが機能として実装されていますが、あまり使い勝手が良くないと思われてます。
シーンにBakeする必要があったり、GameObjectをstaticにする必要があったり、NavMeshAgentは速度と回転率を設定する必要があったり、デフォルトで勝手に移動し始めたり、まぁやっぱりなんか使い勝手悪い気がしてきました。使い勝手悪いです。
ただ、今回はその中の大きな要素の一つである「動的にNavMeshを生成するのがめんどくさい」という思い込みを取り除けると思います。
ちなみに、テラシュールブログや公式のリファレンスなどで「高レベルのコンポーネントを入手する」と称して同コンポーネントが紹介されているので、
「このUnity公式の拡張コンポーネントがないと実行時にベイク出来ないんだ」とちょっと前まで思ってましたがそんなことは無かったです。
煩雑な上にstatic変数で探索対象を管理していて、宗教上私には使えなかったので倦厭してましたが、ちゃんと読み解けばシンプルな使い勝手で良い感じになります。
Unity-Technologies/NavMeshComponents
https://github.com/Unity-Technologies/NavMeshComponents
解説
UnityEngine.AI
-
NavMeshBuildSource
- ナビメッシュを生成する最小単位
- shapeとかsizeとかtransformとか渡す。
MeshFilter
と1:1
-
NavMeshData
- 複数の
NavMeshBuildSource
を持つデータ -
NavMesh
にAddNavMeshData()
で渡す- ナビメッシュを実際に生成する
-
NavMeshBuilder
にUpdateNavMeshDataAsync()
で渡す- ナビメッシュを実際に生成する
- 前回の
AddNavMeshData()
もしくはUpdateNavMeshData()
からの差分だけ更新する
- 複数の
-
NavMeshDataInstance
-
NavMeshData
のInstance。そのナビメッシュが不要になったときにRemove()を呼ぶ -
NavMesh
にAddNavMeshData()
の返り値で渡される
-
SimpleNavMesh
https://github.com/lisearcheleeds/SimpleNavMesh/tree/master/Assets/Scripts/SimpleNavMesh
NavMeshController
コンポーネントの IEnumerator GenerateNavMesh()
を実行すると、
navMeshTargetParent
以下の全ての INavMeshTarget
に対してNavMeshを生成します
- INavMeshTarget
-
NavMeshTargetData
とUpdateNavMeshTargetData()
を持つインターフェイス
-
- MeshFilterTarget
-
MeshFilter
からNavMeshBuildSource
を作るコンポーネント -
INavMeshTarget
を実装する
-
- NavMeshController
- 指定されたGameObjectのHierarchy配下の
INavMeshTarget
を集めてBoundsを計算してNavMeshBuilder.UpdateNavMeshDataAsync()
とか叩くコンポーネント
- 指定されたGameObjectのHierarchy配下の
- NavMeshTargetData
-
NavMeshBuildSource
とBoundsを持つデータ
-
出来なかったもの
高台から落下してショートカットするためにOffmeshLinkも動的に生成したかったんですがどうやるんですかね?
まぁそもそもあまり使わないほうが良い気がする