Unreal Engine5　好きな画像を動かしたい！（2D横スクロール）

# はじめに
フューチャーの関根正大です。
[フューチャー Advent Calendar 2023の13日目](https://qiita.com/advent-calendar/2023/future)になります。

今回はUnreal Engine5を使って、自分のスマホ、PCに保存した画像をキーボードやコントローラーで操作する方法を紹介しようと思います。

今回は以下の画像のように横スクロールゲーム風に操作できるように実装をしてみます。
![スクリーンショット (227)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/1dcf9cc6-5871-363b-5022-6d64fa705eae.jpeg)


# プロジェクトの立ち上げ
それでは最初に新規プロジェクトを立ち上げます。既にプロジェクトを立ち上げていている方は飛ばして問題ありません。
今回はUnreal Engine5.3.2を起動します。
![スクリーンショット (165)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/d207fa60-7329-e877-076c-ba0566015dd1.jpeg)

ブランクを選択し、スターターコンテンツにチェックを入れます。
プロジェクトの場所、プロジェクト名は好きな値を入れて問題ありません。
今回は`C:\GameProject`に`FavoriteImageProject`というプロジェクトを作成します。
![スクリーンショット (166)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/7e03e58b-9730-133b-cb7f-90d29d1b647c.jpeg)

新規プロジェクトが立ち上がったら`ファイル`から`新規レベル`を選択します。
![スクリーンショット (167)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/146e8f55-f85c-3334-63b9-f0446c04e7ac.jpeg)

今回は`Basic`を使います。
![スクリーンショット (168)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/07095a66-e949-7796-e300-443cc2cc1bad.jpeg)

新規レベルが立ち上がったら、`コンテンツ`フォルダ直下に`Maps`というフォルダに`Test`という名前でレベルを保存します。
![スクリーンショット (169)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/5410c6c0-da5c-37ae-131a-b9e120f9c74c.jpeg)

# 好きな画像をインポートする
それではプロジェクトの作成、レベルの作成が完了したので画像のインポートをしていきます。
今回はいらすとやからカモの画像をインポートします。
画像のインポート方法は簡単で、

- コンテンツブラウザにドラッグアンドドロップ
- コンテンツブラウザのインポートから画像をインポート

をする事で取り込めます。
今回は新しく`Character`というフォルダを作成してそこにインポートしていきます。
取り込める画像の拡張子は以下の公式ドキュメントに載っています。
jpegやpngなど代表的なものはほとんどカバーされています。

https://docs.unrealengine.com/5.0/ja/textures-in-unreal-engine/

![スクリーンショット (172)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/a4a2131d-da6c-ee8a-dc67-21343b8be68b.jpeg)

しかしこの画像のままではレベルに配置することは出来ません。
画像を操作出来るフォーマットに変換していく必要があります。
インポートした画像を右クリックし、`スプライト アクション`から`スプライトを作成`を選択します。
スプライトについては公式ドキュメントに説明があったため引用します。
>Paper 2D の スプライト とは、完全に Unreal Engine 4 (UE4) 内で作成されるワールドでレンダリングできる Texture Mapped Planar Mesh (テクスチャ マッピングされる平面的なメッシュ) および関連マテリアルのことです。簡単に言うと、UE4 で 2D 画像を迅速かつ簡単に描画する方法です。

https://docs.unrealengine.com/4.27/ja/AnimatingObjects/Paper2D/Sprites/

![スクリーンショット (173)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/94ab6ae5-933a-4e00-4868-9878ee7aa3d2.jpeg)

上記の公式ドキュメント内にも説明がありますが、スプライトはマテリアルであるため、このままではレベルに配置することはできません。
アニメーション化するためには作成したスプライトを右クリックし、`フリップブックを作成`を選択します。

![スクリーンショット (174)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/1e805ae9-c5d5-0123-8b71-755daadea8a9.jpeg)

これでフリップブックの作成が完了します。
作成されたフリップブックはレベル上に配置することができるようになります。

![スクリーンショット (177)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/5d5c07ff-9e62-eb14-248f-c153b9fbff66.jpeg)

# 作成したフリップブックをキーボードで操作する
## キー入力の設定
手元の画像をレベル上に配置できるようになったため、ここからはこの画像をキーボードやコントローラーで操作する方法を紹介しようと思います。

コンテンツブラウザ上に`Inputs`フォルダを作成し、右クリック、`入力`から`入力アクションを選択します。
![スクリーンショット (178)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/7a549750-2ced-d1df-4938-49ab82528d97.jpeg)

今回は横スクロールゲームを想定して、ジャンプ操作と左右移動操作を実装します。
`IA_Jump`と`IA_Move`という入力アクションを作成します。

入力アクションについてと、この後使用する入力マッピングコンテキストに関しては以下の公式ドキュメントに記載があります。
気になる方は読んでみてください。

https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/Input/

![スクリーンショット (179)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/c90c54ba-f019-8881-4773-785d2a056cfa.jpeg)

まず`IA_Jump`から操作を加えていきます。
とは言いましたが、こちらは手を加えずにデフォルトのままで使用します。
![スクリーンショット (180)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/bfb4ce72-fd78-3b04-2937-100307dbfd43.jpeg)

続いて`IA_Move`を修正していきます。
左右の移動のみを入力として与えたいため、`Value Type`を`Axis 1D(float)`に修正します。

:::note 
IA_Jumpの補足
先ほどの`IA_Jump`のValue Type`は`Digital(Bool)`となっていました。
これはジャンプ入力をしているか、していないか、の二値で判別をしているためになります。
:::
![スクリーンショット (181)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/984d133c-741d-3c58-41e6-f1f4ed22fe8b.jpeg)
次に入力マッピングコンテキストの設定をします。
`Inputsフォルダ`上で右クリック、`入力`から`入力マッピングコンテキスト`を選択します。
![スクリーンショット (182)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/6330e4ac-7fd3-3855-cfcb-07ec280eee79.jpeg)

今回は`IMC_Mapping`という名前で保存しておこうと思います。
![スクリーンショット (183)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/5155e070-5821-a306-5aa1-1c5d20f2b30b.jpeg)

`IMC_Mapping`を開きます。
ここで**どのキーボードの入力を受け付けるか**の設定をしていきます。
まず`Mapping`の横にある⊕ボタンを押します。
![スクリーンショット (184)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/7242b378-d20b-feae-04a2-a3e69847877d.jpeg)

まずジャンプ操作の設定からしていきます。
`なし`と書かれている部分を選択し、`IA_Jump`を選択します。
![スクリーンショット (185)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/3888cc2d-93ff-a06f-2341-3ad7904cc219.jpeg)

次に今設定した`IA_Jump`のその右にある⊕ボタンを押して、キー設定を追加します。
追加されたら、キーボードマークを選択した状態で、ジャンプキーを割り当てたいキーを押下します。
今回はスペースキーをジャンプに割り当てようと思います。
![スクリーンショット (186)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/a45e42fb-4a5f-7fd8-7fee-7ef93512529f.jpeg)
スペースキーを押すと、自動でキーの値が入力されます。
これで、スペースバーと`IA_Jump`を紐づける事が出来ました。
![スクリーンショット (187)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/5b948e1e-c668-06bd-dcc4-1cb523ce14ea.jpeg)
続いて`IA_Move`の設定をしていきます。
今回は右移動は「→（右矢印）」と「D」、左移動には「←（左矢印）」と「A」を割り振ります。
その際に、左移動の「←（左矢印）」と「A」の`Modifiers`を`Negate`に設定する必要があります。
`Modifiers`横の⊕ボタンを押して、`Negate`の設定を追加します。
これは「←（左矢印）」と「A」を押した際に、逆の方向に進んでほしい、つまり負の方向に進むようにするためになります。
![スクリーンショット (188)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/09f45b83-b171-f782-86f3-16afd8fe1c62.jpeg)

最終的にこちらの画面のように設定が出来たら、`IMC_Mapping`の設定は完了となります。
もし他のキー操作を入れたい、ゲームパッドでも操作をしたい場合は同様の手順でさらにキー設定を追加することが可能です。
興味がある方はやってみてください。
![スクリーンショット (189)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/ed1c8682-f2d0-afea-272e-d5d4d65ac9fd.jpeg)

## BluePrintで画像を動かす
ここからは今設定をした内容を用いて、実際に画像を動かしてみようと思います。
`Characterフォルダ`で右クリック、`ブループリントクラス`を選択します。
![スクリーンショット (193)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/dcefe542-2d5f-e2fc-f5bf-cec78cc8e59a.jpeg)

親クラスを選択、という画面が出てきたら検索欄に`Paper`を入力して、`PaperCharacter`を選択します。
![スクリーンショット (194)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/1b48b01f-6246-df7c-0dd0-736e4ef61dad.jpeg)
`BP_Kamo`という名前を付けて保存をしておきます。
![スクリーンショット (195)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/09386638-7fcc-43e9-caf6-98024b7c345b.jpeg)
`BP_Kamo`を開きます。
まず最初に、この`PaperCharacterブループリント`で、どのフリップブックを使用するのか、の設定をします。
詳細パネルの`Source Flipbook`で割くほど作成した`FB_Kamo`を選択します。
![スクリーンショット (196)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/b6890c29-9dfd-4cae-b742-809253abcf5d.jpeg)
するとビューボート上に画像が表示されます。
![スクリーンショット (197)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/221cb00f-6b39-d6a8-21ac-e45c84ee491b.jpeg)

続いて、`Game Mode Base`の設定を行います。
これを設定する事で、ゲームを開始した際にどのBluePrintを操作するようにするか、などを決められます。
コンテンツフォルダ直下で右クリック、`ブループリントクラス`を選択します。
![スクリーンショット (199)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/510f31e3-858a-e090-a901-4e19c929a021.jpeg)
`Game Mode Base`を選択します。
![スクリーンショット (200)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/f70fa964-4ced-8f18-d734-b4b4ac381555.jpeg)

`GMB_GameModeBase`と名前を修正します。
そしたらこちらをクリックして開きます。
![スクリーンショット (201)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/7ebe315d-1115-6a43-f2d3-d2cb7f70c0ff.jpeg)

今回はここで「ゲームが開始された際にどれを操作キャラクターとするのか」を設定します。
今回はゲームが開始された際に`BP_Kamo`がスポーンしてほしいので、詳細パネルの`クラス`から、`Default Pawn Class`を選択し、その中から`BP_Kamo`を選択します。
![スクリーンショット (202)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/6b1c5dfe-5997-46fa-2fb9-8622dafd2731.jpeg)

そしてこの設定が完了したら、`編集`から`プロジェクト設定`を開きます。
![スクリーンショット (203)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/a3a565b6-da4c-9aa0-c3d9-4d1bbf451833.jpeg)

デフォルトのプロジェクト設定では、先ほど設定した`GMB_GameModeBase`が設定されていません。
`プロジェクト`の`マップ&モード`の`選択したゲームモード`を`GMB_GameModeBase`に変更します。
![スクリーンショット (204)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/9615bb5b-f287-d639-379f-8b8825df2ad8.jpeg)

以下の対応は行わなくても問題はありませんが、`Default Maps`の`エディタのスタートマップ`、`ゲームのデフォルトマップ`を`Test`(現在開発しているレベル)に変更しておきましょう。
これで、Unreal Engineを再起動した後、このレベルが最初に開くようになります。
![スクリーンショット (205)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/873c1b83-aace-2f8e-901c-95a93751ec2e.jpeg)

いったんこの状態で再生ボタンを押しましょう。
何も表示されないと思いますが、`F8`キーを押すことで、ゲームを再生している状態でカメラを自由に動かせるようになります。
するとしっかりと設定したカモの画像が表示されていることがわかります。
しかしまだ`BP_Kamo`に先ほど設定した`IA_Jump`や`IA_Move`の情報を渡していないため、操作することができません。
次は`BP_Kamo`のBlue Printを作成していきます。
![スクリーンショット (206)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/44368cc8-c41a-0027-6ae2-7fcde6886329.jpeg)

まずは`Begin`ノードから設定していきます。
以下のようなブループリントを作成します。
一番右にある`Add Mapping Content`の`Mapping Context`には`IMC_Mapping`を設定します。
これにより、ゲーム開始時に、コントローラーの情報を受け取り、どのキーで操作するのか、などの情報を付与することができます。
![スクリーンショット (208)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/cabe9ea7-8454-4128-a9ae-29253077c8c8.jpeg)

続いて`IA_Jump`、`IA_Move`を追加します。右クリックで検索をする事で出てきます。
![スクリーンショット (210)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/9a91a674-2cf7-c53a-62c2-cf6a1752cd2a.jpeg)


`IA_Jump`に関してあhスペースキーが押されたら、ジャンプをするようにしたいです。
しかしキーを押す、というピンは`Triggered`と`Started`の2つがあります。
挙動の違いを見るために、それぞれに`Print String`を設定してみます。
実行してみるとわかりますが、
`Triggered`は押している間毎フレーム実行され、
`Started`はキーを押しこんだ瞬間だけ実行されます。
今回は押した瞬間にだけジャンプをするように設定するため、`Started`を採用します。
対して、`IA_Move`はキーが押されている間はずっと移動をしてほしいため`Triggered`を採用します。
![スクリーンショット (211)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/6471a57f-3c42-af05-cba2-f992138fad01.jpeg)

そうしましたら、以下のようにBlue Printを作成します。
`IA_Jump`は、キーが押された瞬間に`Jump`（Unreal Engineが用意しているメソッド)を呼び出し、
キーが離されたら、`Stop Jump`を呼び出します。

`IA_Move`はもう少し単純で、`IA_Move`が呼ばれたら、`Add Movement Input`で`self`（この場合`BP_Kamo`）に「X座標に1.0」加える、という処理をします。
![スクリーンショット (212)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/506bdec7-7660-fb48-685c-a2f779de8ea8.jpeg)

そして先ほどゲーム開始した際はFPS視点になってしまっていました。
なのでこれを横スクロール風に修正しようと思います。
`BP_Kamo`の`コンポーネント`に`SpringArm`と`Camera`を親子付けして配置します。（`SpringArm`の下に`Camera`が入っていれば大丈夫です。）
![スクリーンショット (213)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/c81ab42c-cb10-365f-3281-d85b4de508f8.jpeg)

正面から画像が見えてほしいので、SprintArmの向きを90度回転させます。
![スクリーンショット (214)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/977c6421-e2b3-4c3a-8f17-c5be0833c196.jpeg)

これでゲーム開始ボタンを押すと、正面にカモが表示されます。
そしてキーボードを押下するとカモが移動しているのを確認できます。
しかし、カモはずっと右に向いているままになっています。
左に移動したら向きを左にするような処理を追加しようと思います。
![スクリーンショット (215)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/1f75ccea-25fa-8c86-3dc2-60752796dc35.jpeg)

`BP_Kamo`の関数に⊕ボタンを押して`UpdateCharacterDirection`を追加します。
![スクリーンショット (216)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/f247945c-2ee0-e9ec-8a5a-7f9d4929ecf1.jpeg)

以下の画像のようにノードを配置します。
`Get Velocity`の部分ですが、今回はX軸方向の移動しかありません。
なのでXの速度だけを取り出そうと思います。
![スクリーンショット (217)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/14df9236-91b5-89b1-5db7-a061ddd0fb1e.jpeg)

`Get Velocity`の`Velocity`ピンを右クリックし、`構造体ピンを分割`を押します。
そして`Velocity X`ピンを`Compare Float`の`Input`ピンに接続します。
![スクリーンショット (218)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/2c550dc1-2837-f3e7-3d9b-81fec05df06f.jpeg)

後は入ってきた`Velocity X`の値が正の時、負の時で条件分岐をさせます。
`IsValid`の部分はクラッシュなどの対策をするために用いられる表現になります。
（以下他の使用例になります）

https://forums.unrealengine.com/t/get-controller-not-valid/473902

そのため、ここでメインで行いたい処理は`Make Rotator`と`Set Control Rotation`の二つになります。
`Velocity X`が正の時、つまり右方向に移動しているときはカモは右を向いていてほしいので、`Make Rotator`には特に値を入れません。
![スクリーンショット (219)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/a618fa6f-50e3-75ee-b34e-a01c8ec07da1.jpeg)

先ほどのノードをコピーし、`Velocity X`が負の時の処理も追加します。
この場合、カモの画像は左を向いてほしいので、`Make Rotator`の`Z`に180の値を入れます。
これで関数は完成になります。
![スクリーンショット (222)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/17b63f2c-f912-ef36-525c-acbd5ad4f80f.jpeg)

今作成した関数を`BP_Kamo`で呼び出さないといけないため、`イベントグラフ`に戻ります。
毎フレーム処理を表す`Event Tick`と先ほどの関数`Update Character Direction`を呼び出します。（画面左の関数からドラッグアンドドロップで配置できます。）
これで処理は完成です！
![スクリーンショット (224)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/1b16abdb-8ec3-7316-7f9a-07410fe09404.jpeg)

しかし実際に動かしてみると、カモはずっと右を向いており、
左向きに移動した際に背景も反転していることがわかります。
これは`Sprint Arm`が常にカモにくっついてしまっているからです。
![スクリーンショット (225)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/c436e3ff-4f89-f592-a663-aaf99244c104.jpeg)

これを修正するには、`Spring Arm`の詳細パネルから、`トランスフォーム`の`回転`を選択し、`相対`から`ワールド`に変更します。
これにより、カモに対する相対座標ではなく、絶対座標で`SprintArm`が配置されるようになります。（カモが回転してもカメラの向きは固定になります）
![スクリーンショット (226)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/6cc2d236-6f73-613d-ca89-e52facaa74cf.jpeg)

実際に実行してみるとカモがしっかりと左を向くことが確認できます！！
![スクリーンショット (227)_R.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549878/1dcf9cc6-5871-363b-5022-6d64fa705eae.jpeg)


# おわりに
今回の内容は以上になります。
自分の好きな画像が、自分が作成したBlue Printで動いているのを見ると楽しいですね。

明日のアドベントカレンダー担当は[@yamat2667](https://qiita.com/yamat2667)さんからになります！

# 参考にした書籍やサイト

https://www.udemy.com/course/unreal-2d-course/

https://docs.unrealengine.com/5.3/ja/

https://www.youtube.com/playlist?list=PLr_Cbd4sUDTzbVjg1Bsm5s_21uPQ4xHLx