[UE4] Nav Link Componentを使用してゲーム内でナビメッシュをつなぐ

# はじめに
アクタの追加により地形が変化するような状況で動的にナビメッシュを追従するようにしたときに、段差がある場合そのままではナビメッシュが分かれてしまうため、AIが段差を超えて移動することができません。
Nav Link Componentを使用することで、ナビメッシュをつないで段差を超えて移動するようにできました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">VRでもナビメッシュが見えました<a href="https://twitter.com/hashtag/UE4?src=hash&amp;ref_src=twsrc%5Etfw">#UE4</a> <a href="https://twitter.com/hashtag/UE4Study?src=hash&amp;ref_src=twsrc%5Etfw">#UE4Study</a> <a href="https://t.co/QeOnLaMWEx">pic.twitter.com/QeOnLaMWEx</a></p>&mdash; 高浜 (@SatoshiTakahama) <a href="https://twitter.com/SatoshiTakahama/status/1485910150074728450?ref_src=twsrc%5Etfw">January 25, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 環境
Windows10
UnrealEngine 4.27.2 (最近エディタの言語設定を英語に変更しました)

# 作り方(まずは動的にナビメッシュを更新するところまで)
・プロジェクトの設定でGenerate Navigation Only Around Navigation Invokersのチェックボックスをオンにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/9ce2cc0c-2626-108a-4387-dcdd28473033.png)

・Runtime generationをDynamicに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/3dc7e1b2-1a9e-e5b3-bd19-3ce6c589cb93.png)

・レベルに大きめにNavMeshBoundsVolumeを配置します。あとでナビメッシュを追加する可能性がある範囲が含まれるようにします。大きくしても処理負荷には影響ないはずです。

・ナビメッシュを使用したいキャラクターにNavigation Invokerを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/40c6aecd-662e-d10e-8855-f4fe7aca65e5.png)

# 作り方(ナビメッシュをつなぐ)
・追加する地形のアクタにNav Link Componentを追加します。この例で追加する地形は100x100x100の立方体のブロックとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/7c5ce94f-de61-786e-b2bd-2c34fc3a0372.png)

・Nav Link Componentにリンクを設定します。ブロックの上方から上下左右4方向に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/e3745cad-0337-b178-6fa7-60009900bfec.png)

・AIで制御するキャラクターのCharacter MovementのMax Step heightの設定を変更しておきます。ここで段差より大きい値に設定しておかないと、段差を超えて移動できないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/33131207-51a8-5ef1-9f10-c5436fda2709.png)

・ゲーム中に地形のアクタをSpawnすると、地面のナビメッシュとブロック上方のナビメッシュが繋がれた状態になります。

# 参考資料
・[ナビゲーション機能を提供するクラス-1](https://qiita.com/EGJ-Ken_Kuwano/items/53c1ecc3f19958183887)
Nav Link Componentの存在はこちらで知りました。Nav Link Componentは公式ドキュメントでも説明が見つけられず、
情報が少ないので助かりました。

・[Navigation Invokerを使用する](https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/ArtificialIntelligence/NavigationSystem/UsingNavigationInvokers/)
Navigation Invokerの使用方法についての公式ドキュメントです。

・[ナビゲーション メッシュ生成速度を最適化する](https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/ArtificialIntelligence/NavigationSystem/OptimizingNavigationMeshGenerationSpeed/)
ナビメッシュの処理負荷を調整するときの参考になりそうです。今のところは処理負荷はあまり重くなさそうな雰囲気なので調整していないですが。

# 追記
ここまで書いておいてなんですが、Nav Link Componentを使用したこれまでの実装だと、段差を超えるときに瞬間移動のような挙動になってしまいます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">段差の移動がぎこちない動きになっている・・<br>ジャンプのアニメーションをさせたいけどやり方がわからない・・<a href="https://twitter.com/hashtag/UE4?src=hash&amp;ref_src=twsrc%5Etfw">#UE4</a> <a href="https://twitter.com/hashtag/UE4Study?src=hash&amp;ref_src=twsrc%5Etfw">#UE4Study</a> <a href="https://t.co/WeWDGeeJgE">pic.twitter.com/WeWDGeeJgE</a></p>&mdash; 高浜 (@SatoshiTakahama) <a href="https://twitter.com/SatoshiTakahama/status/1486332440121851905?ref_src=twsrc%5Etfw">January 26, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

自然な動きにするためには、Nav Link Componentではなく、Nav Link Proxyを使ったほうが良いです。
最初アクタにはNav Link Proxyをつけられないと思い込んでいてNav Link Componentを使用したのですが、ChildActorを使用すればNav Link Proxyをつけられます(下のBP_JumpLinkProxyはNav Link Proxyを継承したBP)。Nav Link Componentの時と同じように4方向にSimple Linkを設定しておいて、下から上に移動するときにSmart Linkでイベント発生=>キャラクターにジャンプさせます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/9b2d0003-0194-2c10-b628-ef93832df1cb.png)

Nav Link Proxyの使い方は、こちらの記事 [【UE4】Nav Link Proxy を使ってAIにジャンプをさせる](https://qiita.com/Dv7Pavilion/items/0250474f93934caf1815) が詳しいですので参考にするとよいと思います。
修正後は以下のような動きになりました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">猫の上に猫が乗るのだけれど、お互いあまり近づかない制御が必要かな・・<a href="https://twitter.com/hashtag/UE4Study?src=hash&amp;ref_src=twsrc%5Etfw">#UE4Study</a> <a href="https://t.co/0ZqGv1EQSD">pic.twitter.com/0ZqGv1EQSD</a></p>&mdash; 高浜 (@SatoshiTakahama) <a href="https://twitter.com/SatoshiTakahama/status/1486680542418718725?ref_src=twsrc%5Etfw">January 27, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>