【UE4】Nav Link Proxy を使ってAIにジャンプをさせる

#はじめに
![1.png](https://qiita-image-store.s3.amazonaws.com/0/104467/0ed76d2b-f7af-873e-e364-f95294d7a7f9.png)
図のような段差や穴、壁等を登ったりする際には赤線のような望ましい軌道というのがあると思います。今回はこのような**弧を描いたジャンプ**をAIにさせます。

使用するプロジェクトテンプレートは**「Third Person Template」**です。
プロジェクト名は適当でOKです。

#AI CharacterとAI Controllerの作成
キャラクターを継承した**C_Jumper**
![4.png](https://qiita-image-store.s3.amazonaws.com/0/104467/ee17ae13-7c1a-d6d2-6c66-beccb9534917.png)

AI Controllerを継承した**AIC_Jumper**を作成します。
![5.png](https://qiita-image-store.s3.amazonaws.com/0/104467/dada70c7-795f-cdd0-a197-5db15c42c04c.png)

**※作成したC_JumperのAI ControllerにAIC_Jumperを設定するのを忘れずに**![6.png](https://qiita-image-store.s3.amazonaws.com/0/104467/477e9cf2-f52d-f504-4c60-c814c4893983.png)


#Nav Link Proxyの作成
Nav Link Proxyを継承して新しくジャンプ用のNav Link Proxyを作成します。
![2.png](https://qiita-image-store.s3.amazonaws.com/0/104467/eb8357ca-23ff-3737-ec32-d4179a609c01.png)
名前を**JumpLinkProxy**とします。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/104467/43db7550-63be-3d51-98b1-76012eed92d1.png)


#C_Jumperキャラクターのブループリント
変数
![14.png](https://qiita-image-store.s3.amazonaws.com/0/104467/1e4bfa40-5381-3408-8af9-92ddf01393d8.png)


BeginPlay
![7.png](https://qiita-image-store.s3.amazonaws.com/0/104467/d7b94b2c-3ff7-606f-d6f0-bec897f4ad61.png)

Tick
![8.png](https://qiita-image-store.s3.amazonaws.com/0/104467/d3a80578-b64c-4383-9148-3dd02d36401b.png)

BeginPlayとTickの両関数の処理を作成し終わったら、カスタムイベントを追加します。
![9.png](https://qiita-image-store.s3.amazonaws.com/0/104467/d102d530-bcaa-8b69-6ba3-d4ddd67467d4.png)

Do Jump Requestイベントのインプットに**Vector型**の**Dest Loc**を追加するのを忘れないようにしてください。
このイベントがAIにジャンプをさせる一番大事な所ですが、今は書かずに後に回します。


#JumpLinkProxyのブループリント
![10.png](https://qiita-image-store.s3.amazonaws.com/0/104467/bfae9922-75f6-dd50-3d7f-e2f346adceb5.png)

Receive Smart Link Reached はAIがNav Linkのいずれかの両端に到達した時に呼ばれるイベントで、到達した側とは反対にあるNav Linkの位置を返します。
![11.png](https://qiita-image-store.s3.amazonaws.com/0/104467/08832105-8b78-c8d3-de13-e20ec11bd629.png)

最後にツールバーにあるクラスのデフォルトをクリックし**Smart Link**の**Smart Link Is Relevant**のチェックを入れてください。
![12.png](https://qiita-image-store.s3.amazonaws.com/0/104467/e0dbbd99-f8a5-ce9b-d0c2-2c5b20a861a9.png)


#最初のテスト
とりあえずジャンプはしませんが、一通り処理を呼び出すように作成したのでレベル上にテスト用の地形を作り、JumpLinkProxyを配置して動作確認してみます。
自分は以下のように作ってみました。
![13.png](https://qiita-image-store.s3.amazonaws.com/0/104467/e5241b42-ca62-4090-ef68-9072711fc270.png)

配置したC_Jumperをクリックし詳細パネルでターゲットポイントを両方設定します。
![15.png](https://qiita-image-store.s3.amazonaws.com/0/104467/d4896ace-d96e-b032-5216-d1f5eff7b497.png)

では、実行してAIの様子を見てみます。

#Nav Link Proxyの罠
如何でしょうか？JumpLinkProxyのイベントやC_Jumperのイベントは呼ばれていますか？恐らくイベントは呼ばれずPrint Stringに設定した文字列は画面上に描画されていないと思います。
ただ、JumpLinkProxyを置いただけではReceive Smart Link Reachedイベントは呼ばれません。
JumpLinkProxyをレベル上に配置したとき、位置を調整するためにダイヤ型のワイヤフレームがついているオブジェクトを移動したはずです。
![17.png](https://qiita-image-store.s3.amazonaws.com/0/104467/183c365b-0177-83c5-725a-cc5434abb48c.png)
これを動かした時はJumpLinkProxyのSimple Linkプロパティの値が変化します。
![16.png](https://qiita-image-store.s3.amazonaws.com/0/104467/f93e9b0a-ed3e-894b-a5a2-aaa58f83b5b1.png)
実はこのSimple LinkというのはJumpLinkProxyでチェックを入れた**Smart Link Is Relevant**にある**Smart Link**とは別物のリンクです。
イベントReceive Smart Link Reachedの名前にあるとおり通知を受け取るのは**Smart Linkに到達した時**ですので、Simple Linkをしっかり設定したとしても、Receive Smart Link Reachedが呼ばれることはありません。

#JumpLinkProxyのプロパティを修正して再度実行確認
では、きちんとReceive Smart Link Reachedが呼ばれるようにレベル上に配置したJumpLinkProxyのプロパティを修正します。
![18.png](https://qiita-image-store.s3.amazonaws.com/0/104467/54747c73-9983-a188-8c19-d81ccfa34013.png)
Simple Linkの**Left、Right**の値をSmart Linkの**Start、End**にコピーして貼り付けるだけです。

では実行して動作確認してみます。
今度は画面上にきちんとPrint Stringの文字列が描画されたはずです。
JumpLinkProxyのReceive Smart Link Reachedイベントにブレークポイントを置けば、そこで動作が停止してフォーカスされると思います。

これでReceive Smart Link Reachedイベントが呼ばれるようになり、AIにジャンプをさせる用意が出来ました。

#AIにジャンプをさせる
内容はかなり単純で２つの関数を呼び出すだけです。
![19.png](https://qiita-image-store.s3.amazonaws.com/0/104467/05b9b41b-6e81-b818-c4c3-d7c9fd22f915.png)
Launch Multのデフォルト値には**1.25**を設定してください。

関数SuggestProjectileVelocity Custom Arcは面白い関数で、Arcと付いているようにStart PosからEnd Posまでを弧で結びます。その結んだ弧をなぞるような加速度を求める関数です。
![20.png](https://qiita-image-store.s3.amazonaws.com/0/104467/538ccde5-5679-9418-b88b-f7423aea47f1.png)

その次にある関数Launch Characterはキャラクターを好きな方向に打ち出す関数です。Projectileとは違い、この関数が動作する対象はキャラクターのみのようです。

SuggestProjectileVelocity Custom Arcで求めた加速度をLauch Characterに渡すことで、ジャンプのような動作を実現できます。

実際に動作を確認してみるとしっかりとジャンプをしてくれるはずです。
![asdf.gif](https://qiita-image-store.s3.amazonaws.com/0/104467/1c72d7f8-e0a2-43ae-87fe-9b5970719681.gif)

#おわりに
SuggestProjectileVelocity Custom ArcとLauch Characterを使ったAIのジャンプは最近MODツールが発表され、UE4で無料で触れる**RoboRecall**での処理を参考にしました。
皆様も是非遊べなくともソースを覗いてみると面白い発見があるかもしれません。

以上です。お疲れ様でした。