［UE5］三人称カメラの視点を3段階で切り替えられるようにする

# 概要
この記事では、Unreal Engine 5 で、下の動画のように、三人称カメラの視点を3段階で切り替えることができるようにします。

<iframe width="640" height="360" src="https://www.youtube.com/embed/_y6oafh7xAI" title="3 camera 3" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


# この記事の主な対象者
- Blueprint（BP）の作り方の基礎を習得されている、初心者の方


# 事前準備
今回の記事では、作成を簡略化するために、Unreal Engine のテンプレートプロジェクトである「Third Person」プロジェクトの中に入っている、プレイヤーのBP「BP_ThirdPersonCharacter」を使用します。

ですので、今回の記事のものを作成され始める前に「BP_ThirdPersonCharacter」をプロジェクトの中に入れておくようにしてください。

何卒、よろしくお願いいたします。


# 1. 3つのカメラアクタを保持したプレイヤーを作成する

カメラの視点を3段階で切り替える方法としては、プレイヤーに3つのカメラを保持させ、切り替えるというようにします。

Camera コンポーネントを視点切り替え用のカメラとして使用しても、上の完成動画のように滑らかにカメラを切り替えることができないようになっています。視点を滑らかに切り替えるようにするためには、Camera コンポーネントを保持したアクタを切り替え用のカメラとして利用する必要があります。


なので最初に、視点切り替えに使用するカメラのアクタのBPを作成します。（今回の記事では、作成するカメラアクタのBPの名前を「BP_BaseCameraActor」にします。）

下図のコンポーネントようなコンポーネント構成のBPを作成します。

![basecameraactor.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/fabb660d-39a2-53a7-3a74-71de15cda19c.jpeg)

|コンポーネント名|コンポーネントの種類|備考|
|:-:|:-:|:--|
| DefaultSceneRoot | Scene | このコンポーネントを一番上の親にします。 |
| Camera | Camera | プレイヤーに持たせる視点切り替え用のカメラとして使用します。 |

<br>

プレイヤーに持たせるようのカメラアクタを作成したら、次は事前準備していただいた「BP_ThirdPersonCharacter」を開き、「BP_ThirdPersonCharacter」のコンポーネントに、下図の赤枠のコンポーネントを追加します。

![components.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/b289c44a-e295-0efe-1ff1-5e117776e0a7.jpeg)

|コンポーネント名|コンポーネントの種類|備考|
|:-:|:-:|:--|
| SpringArmTop | Spring Arm | プレイヤーから一番離れた位置にあるカメラに紐づけるSpringArmです。 |
| CameraTop | Child Actor | プレイヤーから一番離れた位置にあるカメラのアクタです。 |
| SpringArmBottom | Spring Arm | プレイヤーから一番近い位置にあるカメラに紐づけるSpringArmです。 |
| CameraBottom | Child Actor | プレイヤーから一番近い位置にあるカメラのアクタです。 |
| SpringArmMiddle | Spring Arm | プレイヤーから二番目に近い位置にあるカメラに紐づけるSpringArmです。 |
| CameraMiddle | Child Actor | プレイヤーから二番目に近い位置にあるカメラのアクタです。 |

<br>

Child Actor コンポーネントである、「CameraTop」「CameraBottom」「CameraMiddle」コンポーネントでは、それぞれ詳細パネルを開き、詳細パネルの「チャイルドアクタコンポーネント」「Child Actor Class」に、上で作成したカメラのアクタのBP「BP_BaseCameraActor」を設定するようにします。

![childactorclass2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/1df47c90-aff5-cae0-c46e-f598adb31e0b.jpeg)

また、「SpringArmTop」コンポーネントの詳細を開き、「カメラ」＞「Target Arm Length」にプレイヤーからのカメラの距離を設定します。「SpringArmBottom」コンポーネントには、「SpringArmTop」コンポーネントの値よりも小さい値を設定し、「SpringArmMiddle」コンポーネントには「SpringArmTop」「SpringArmBottom」コンポーネントに設定した値の中間の値を設定します。
（今回の記事では、「SpringArmTop」コンポーネントは「800」、「SpringArmBottom」コンポーネントは「600」、「SpringArmMiddle」コンポーネントは「400」を設定するようにします。）

![springarm_targetarmlength.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/5862e616-e742-2b10-fe5e-8b3a25f57b63.jpeg)<br><br>



上の表のコンポーネントを追加したら「BP_ThirdPersonCharacter」についているカメラが、マウス操作に合わせて動くようにします。


「SpringArmTop」コンポーネントの詳細パネルを開き、詳細パネルの「カメラセッティング」＞「Use Pawn Control Rotation」にチェックを入れます（下図の赤丸）。

![springarm_usepawncontrolrotation.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/1adde8ce-f378-68e0-5969-56d5ae33a43c.jpeg)

同様にして、「SpringArmBottom」コンポーネントと、「SpringArmMiddle」コンポーネントの「カメラセッティング」＞「Use Pawn Control Rotation」にもチェックを入れます。

これで「BP_ThirdPersonCharacter」では、カメラがマウス操作に合わせて動くようになり、切り替える用の3つのカメラを保持したプレイヤーの作成は完了です。



# 2. 3つのカメラに視点を切り替えられるようにする

最初に、上で3つのカメラアクタを追加したプレイヤーのBP「BP_ThirdPersonCharacter」のイベントグラフを開き、視点切り替えの処理の実装に必要な変数を作成していきます。

まずは、カメラの切り替え時間を指定するための変数を作成します。変数の型は「Float」にします。（今回の記事では、変数名を「SwitchingCameraTime」にします。）

![switchingcameratime.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/f5227ed1-7ab9-c51b-2a55-6846573491fd.jpeg)<br><br>


次に、切り替える用のカメラのアクタを保持しておくための変数を作成します。変数の型は「Actor」にし、配列にします。（今回の記事では、変数名を「CameraActorArray」にします。）

![cameraactorarray.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/a288cabf-ac35-e6ee-baf7-c60930b07b20.jpeg)<br><br>


最後に、現在画面を映すのに使用しているカメラの、「CameraActorArray」における番号を保持しておくための変数を作成します。変数の型は「Integer」にします。（今回の記事では、変数名は「CrntCameraIndex」にします。）

![crntcameraindex.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/054ab875-b35c-96ef-9cd2-0c9d78a5c7e1.jpeg)

これで、視点切り替えの処理の実装に必要な変数の作成は完了です。<br><br>


変数の作成が終わったら、視点切り替えの処理の実装で使用する関数を作成します。

まずは、下図の関数を作成します。下図の関数では、切り替えるカメラを管理する配列「CameraActorArray」の初期化を行います。**プレイヤーからの距離順で配列にカメラのアクタを追加する**ようにします。

![initcameraactorarray.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/2f81e3f8-492a-d466-0d77-ac3ac3f907a3.jpeg)<br><br>


次に、下図の関数を作成します。下図の関数では、インプットで受け取った番号に対応した、配列「CameraActorArray」のカメラアクタを取得します。（今回の記事では、関数の名前を「GetCameraActorFromArray」にします。）

![getcameraactorfromarray.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/222fe310-6361-03d1-7461-f0f1346b58ab.jpeg)

「GetCameraActorFromArray」関数のインプットとアウトプットは、下図のようにします。

![getcameraactorfromarray_‌init.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/aaf8b0cc-2d88-7521-7cb2-c73a76e8ff21.jpeg)<br><br>


最後に、下図の関数を作成します。下図の関数では、インプットで受け取った番号に対応した、「CameraActorArray」のカメラアクタに、カメラを切り替えます。滑らかにカメラの切り替えを行うために、今回の記事では、「Set View Target With Blend」ノードの「BlendFunc」（下図の赤枠）には「VTBlend Ease in Out」を設定し、「Blend Exp」（下図の黄色枠）には「2.0」を設定します。（今回の記事では、関数の名前は「SwitchCamera」にします。）

![switchcamera1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/08abcee9-79e9-5d0b-33fe-29eea5e88381.jpeg)

「SwitchCamera」関数のインプットは、下図のようにします。

![switchcamera_inputoutput1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/30b63332-0328-772b-dbd5-f4e1183f4441.jpeg)<br><br>



視点切り替えの処理の実装で使用する関数を作成し終えたら、視点切り替えの処理の実装を行っていきます。

下図のノードを組みます。
プレイヤーがスポーンされたときに、視点切り替えに使用する変数の初期化を行うとともに、最初に設定すべきカメラに、視点を切り替えます。最初のカメラには、滑らかにカメラ切り替えを行う必要はないので、「Set View Target With Blend」ノードの「Blend Time」（下図の赤枠）には「0.0」を設定します。

![beginplay.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/b44038d8-96d1-6884-8b82-21c0f1879f0a.jpeg)<br><br>


次に、下図のノードを組みます。
特定のボタンが押されたら、カメラを、プレイヤーからより遠くのカメラに切り替えます。（今回の記事では、遠くのカメラに切り替えるボタンを、プレイヤーの操作とかぶらない「L」キーとします。）

![addindex1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/753e3c9c-9ee3-48a5-e818-cf6e1a235856.jpeg)<br><br>


最後に、下図のノードを組みます。
特定のボタンが押されたら、カメラを、プレイヤーからより近くのカメラに切り替えます。（今回の記事では、近くのカメラに切り替えるボタンを、プレイヤーの操作とかぶらない「K」キーとします。）

![subindex1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/a2a7c363-c92c-760a-f9a8-ec1d1676ba12.jpeg)<br><br>


これで、3段階でカメラの視点切り替える処理の実装は完了です。
下の動画のように、3段階でカメラの視点を滑らかに切り替えることができるか確認します。

<iframe width="640" height="360" src="https://www.youtube.com/embed/c-oPdCiWZgU" title="3 camera 1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<br><br>

しかし、この状態では下の動画のような問題点があります。

<iframe width="640" height="360" src="https://www.youtube.com/embed/aMcTmcJXSGw" title="3 camera 2" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<br><br>


上の動画化から分かるように、この状態では、**カメラ切り替え中にカメラを切り替える**ことができてしまいます。

つまり、「カメラ0」→「カメラ1」に切り替えているときに、「カメラ1」→「カメラ2」に切り替えることができ、「カメラ0」→「カメラ1」の切り替え中に、強制的にカメラの位置が「カメラ1」になり、「カメラ2」への切り替えが始まってしまうのです。

なので、次はカメラ切り替え中にカメラ切り替えを行えないようにします。


# 3. カメラ切り替え中に、次のカメラ切り替えを行えないようにする

カメラ切り替え中に、次のカメラ切り替えを行えないようにするために、最初に下図の「Boolean」型の変数を作成します。下図の変数は、カメラ切り替え中は「true」となっているようにします。（今回の記事では、変数名を「IsSwitchingCamera」にします。）

![isswitchingcamera.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/f8b6c871-fe2b-d332-60ce-a955304dc1db.jpeg)<br><br>


次に、上で作成したカメラ視点切り替えのための関数「SwitchCamera」を下図のようにノードを組みなおします。
カメラを切り替えることができたかどうかを、アウトプットで取得できるようにします。

![switchcamera2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/c01420d2-41ef-a3ad-bd51-13e8c2850f94.jpeg)

「SwitchCamera」関数のアウトプットとして、下図の変数を設定します。（下図では途切れてしまっているのですが、今回の記事ではアウトプットの変数名は「HasSwitchedCamera」にします。）

![switchcamera_inputoutput.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/0e2753cc-aade-9ee4-ca54-80d2afe04a53.jpeg)<br><br>


次に、特定のボタンが押されたら、カメラを、プレイヤーからより遠くのカメラに切り替える処理のノードを、下図のように組み替えます。カメラの切り替え中は、次のカメラ切り替え処理を行えないようにします。

![addindex2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/466ba267-4cba-a6ca-806d-df64d83956d0.jpeg)

下の2つの図は、上図を拡大して、2つに分けた図です。

![addindex2_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/6840eaae-a7de-a194-411a-160aac0f8054.jpeg)

![addindex2_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/234094b8-bafa-32f6-cf03-3b6d5810e0b2.jpeg)<br><br>


最後に、特定のボタンが押されたら、カメラを、プレイヤーからより近くのカメラに切り替える処理のノードを、下図のように組み替えます。カメラの切り替え中は、次のカメラ切り替え処理を行えないようにします。

![subindex2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/b409a55b-cd59-0a72-b082-2b51f213b8b7.jpeg)

下の2つの図は、上図を拡大して、2つに分けた図です。

![subindex2_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/c79daf8f-72ee-0aa5-8e52-34b506a3f865.jpeg)

![subindex2_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/2e0e6f8f-37a2-fe3c-3cd6-be035a1cefda.jpeg)<br><br>


これで、カメラ切り替え中に次のカメラ切り替えが行えないようにする処理の実装は完了です。

下の動画のように、カメラ切り替え中に次のカメラ切り替えが行えないようになっているか確認します。

<iframe width="640" height="360" src="https://www.youtube.com/embed/_y6oafh7xAI" title="3 camera 3" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<br><br><br>



以上で今回の記事の内容は終了です。
最後まで読んでいただき、ありがとうございました。