【UE4】操作キャラクターを動的に切り替える

#はじめに
オープンワールド型ゲームによくある**車両への乗り込み＆操作**を実装してみます。
この記事では人や車に関わらずプレイヤーが操作可能なオブジェクトを全て**「操作キャラクター」**と呼んでいます。

#プロジェクトはこちら
使用バージョン：UE4.22.0
https://1drv.ms/u/s!Au-8FqgREBKZhnnd8kpshPPWDZBf

#シンプルに実装してみる
これから紹介するブループリントは「PawnVehicleControl\Simple」フォルダにあります。

![2019-04-10_21h44_22.png](https://qiita-image-store.s3.amazonaws.com/0/104467/d65fdd87-b5a8-947c-e9cd-293b1ebd093e.png)


実は操作キャラクターを切り替える事自体は何も難しいことはありません。
UE4では**Player Controller**というオブジェクトがあるので

1. 人キャラクターからPlayer Controllerを外す（Un Possess）
2. 操作したい車キャラクターにPlayer Controllerを繋ぐ（Possess）

といった手順で**Player Controllerの接続先を変更するだけで操作キャラクターを動的に変える**ことができます。

PawnVehicleControl\Simpleフォルダには２つのブループリントがあります。それぞれ操作可能な人と車を表します。これらはThirdPersonテンプレートとVehicleテンプレートからコピーしました。

まずBP_TestThirdPersonブループリントを開きます。色々と処理がある中で次の画像のような処理があるはずです。

![2019-04-10_21h50_20.png](https://qiita-image-store.s3.amazonaws.com/0/104467/0ea3b620-856c-4d38-68ad-f38f734205e6.png)

この部分が**「人から車へ操作キャラクターを変更する処理」**です。
必要な処理はこれだけです。これ以外の設定はThirdPersonテンプレートから一切変更していません。

処理の流れですが、Eキー（乗り降りボタン）が押された後

1. 衝突判定を利用し近くにあるVehicleを探す
2. ループ開始（何台か見つかる可能性があるため）
3. 操作可能なVehicle型に変換（失敗すれば次の配列要素へ）
4. Un Possessノードを用いてBP_TestThirdPersonからPlayer Controllerを外す
5. Possessノードを用いてPlayer Controllerを３番から取得したオブジェクトと繋げる
6. （ここからは「車へ乗り込んでる感」を出すための処理で操作キャラクターの動的変更そのものには関係ない）
7. BP_TestThirdPersonのコリジョンを無効化
8. Vehicleへの位置へと移動しトランスフォームの親子関係を作成
9. 位置の微調整（そのままだとBP_TestThirdPersonが地面に埋まってしまうため）
10. ループから抜ける

といった感じになります。

次にBP_TestSedanです。

![2019-04-10_22h11_49.png](https://qiita-image-store.s3.amazonaws.com/0/104467/30afe05a-0443-f444-1f78-92a8e0aba17a.png)

乗り込んでいる人キャラクターを取得するためGet Attached Actorsノードを使っています。
以降の手順はBP_TestThirdPersonと同じです。Player ControllerをUn Possessして、乗り込んでいる人キャラクターへPossessします。
「車から降りた感」を出すため、運転席の横に立つように位置調整をしてコリジョンを有効化すれば完了です。

以上の処理でゲーム中に操作キャラクターを変更することができます。

#礼儀正しく実装してみる
操作キャラクターを動的に変える方法そのものには関係ないのですが、Unreal EngineのドキュメントにあるPlayer Controllerページには
> ただし、 1 つのゲーム クライアント上に複数のプレイヤーがいたり、ランタイム時にキャラクターを動的に変更できるようにするなど、より複雑なニーズがある場合は、 入力は PlayerController で処理する方が良いでしょう。このケースでは、 PlayerController が何をするかを決定してから、ポーンにコマンドを発行します ("start crouching" 、 "jump" など)。
http://api.unrealengine.com/JPN/Gameplay/Framework/Controller/PlayerController/

とあります。せっかくなのでドキュメントのとおりに実装してみたバージョンもプロジェクトに含まれているので紹介します。

これから紹介するブループリントは「PawnVehicleControl」フォルダにあります。
![2019-04-10_22h56_44.png](https://qiita-image-store.s3.amazonaws.com/0/104467/945be8a7-4687-0fba-e7db-14f9113e3a86.png)

まず必要なものはPlayerControllerクラスを継承したブループリントとコントローラーと操作キャラクターを繋ぐインターフェースクラスです。
これらはそれぞれ「BP_PlayerController」と「BPI_ControllablePawn」というブループリントという名前で実装されています。

**Input Axsisノード**や**Input Actionノード**の振る舞いはキャラクターの方に直接実装していましたが、これをBP_PlayerControllerにそのまま移します。
![2019-04-11_12h30_24.png](https://qiita-image-store.s3.amazonaws.com/0/104467/fce08b02-63aa-c120-e360-7a23208f806c.png)

BP_PlayerControllerではプレイヤーが操作出来る全てのコマンドをインターフェースを通じて接続しているPawnに送信します。

>インターフェースを通さない場合は次のような記述になります。
![2019-04-11_12h44_11.png](https://qiita-image-store.s3.amazonaws.com/0/104467/d9bc6f7e-01ac-de6d-6ceb-ccb79199ff07.png)

操作キャラクターでイベントとして定義していたInputAxsisノードやInputActionノードは全てインターフェースで宣言した関数名に置き換えます。
![2019-04-11_12h47_45.png](https://qiita-image-store.s3.amazonaws.com/0/104467/7285dabf-fb8a-0cb0-3117-f62c92ddd954.png)

全ての置換作業が終わればドキュメントがオススメする通りの実装が完了します。

#おわりに
操作キャラクターを動的に変えることは全く難しいことでは無いです。
**「Player ControllerをUn Possessし、操作したいキャラクターにPossessする」**
とすれば実現できます。

>書き終わって気づきましたが公式ドキュメントにもプレイヤーキャラクターを切り替える方法がありました。
http://api.unrealengine.com/JPN/Gameplay/HowTo/PossessPawns/Blueprints/index.html

Player Controllerとインターフェースを活用すれば人や車との切り替えだけではなく、GTAのようなバイクや自転車、飛行機、水上バイク等々の多種多様な乗り物にも対応しやすくなります。またNPCに憑依して操作するといった「The 3rd Birthday」のようなシステムも実現出来るかと思います。