[UE] アイテムをキャプチャしてUIに表示しよう

アイテムを3Dで表示したい
-

![key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/0307eba2-37f8-95fb-d5a7-b940b29ef514.png)
バイオハザードヴィレッジのように、アイテムを3Dで表示したい！

今回の成果
-
画像のようにアイテムの表示、回転、切り替え機能ができました。
![ezgif-1-8737e57e24.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/6dfefba4-2965-d7e1-9bfc-75a85fd25958.gif)
今回の内容はBPのみで完成できますので初心者も簡単に作れます。C++を使う必要がありません。UE5 Previewで作りましたが、UE4も同じ手順でできます。
完成したプロジェクトは[Github](https://github.com/strangechu/UICapture)に置きましたのでよかったら参考してください。

キャプチャから表示するまで
-
アイテムを表示するまで、手順は以下：
1. SceneCapture2Dを使って、アイテムの画像をRenderTargetにキャプチャする
2. RenderTargetの画像をTextureに書き込む
3. UIに表示する

Blankプロジェクトからやります。
まずはBlueprintActorを追加して、BP_UICaptureActorと名付けます。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/31e63c11-332b-004d-0198-cfa391ab8275.png)
BP_UICaptureActorの中にStaticMeshとSceneCaptureComponent2Dを追加します。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/d0dd1741-8317-88d1-b12b-d3f334db29c6.png)
カメラがアイテムを撮影するように位置を調整します。StaticMeshにモデル（アイテム）をアサインします。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/dafad8ee-e80a-e77c-495a-d15f48ba8a92.png)
SceneCapture2DのTextureTargetプロパティに、RenderTargetを追加します。RT_UICaptureと名付けます。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/79febdfe-d966-97f5-4251-51f673dca8e8.png)
新規Textureアセットを追加します。T_UICaptureと名付けます。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/a2196d43-8a97-5ac5-8e22-e70e6123c0dc.png)
T_UICaptureを開いて、以下の設定をします
Material Domain: User Interface
Blend Mode: Translucent
これでUI用のAlpha入りのテクスチャになります。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/ac162edb-3e3a-5745-78ef-5df5f703f244.png)
SceneCaptureComponent2Dからキャプチャした画像のAlphaが反転してますので、元に戻す処理が必要です。
T_UICaptureのMaterial Graphに右クリック、TextureSampleを追加します。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/723b85c8-bd8a-67fc-b9ea-5899462957cc.png)
1-xノードも追加し、画像のように繋ぎ、TextureSampleのTextureをRT_UICaptureを指定します。
これでアルファ回転の仕組みができました。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/7e21401b-78ed-6580-a4cb-01c6dea20d2b.png)
これでキャプチャしたものを表示する作業は大体完了です。成果を見てみましょう。
まず簡単なUMGを作って、Imageを追加して、画像をT_UICaptureに設定します。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/304164ef-59d9-f1b9-04ec-309b2ae5a17a.png)
レベルBlueprintで作ったUIを表示します。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/a6199917-21cf-41e2-968d-b99f451f543f.png)
通常、表示するアイテムを動的に生成するのは正しいが、今回はプレビューなので、まずBP_UICaptureActorをそのままマップにドロップします。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/64b9a3ba-4eef-4b87-92de-2e016b95d164.png)
プレイを押したら、アイテムが表示されました！やった！
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/f10e2e54-4f23-246e-46c0-7f1e14005023.png)
って背景も入ってるじゃないですか！心配しないで。背景を透明にすることはできます。

背景を透明にする
-
BP_UICaptureを開きます。SceneCaptureComponent2DのPrimitiveRenderModeをUseShowOnlyListに設定します。これで特定のアクターのみキャプチャするようになります。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/e0cb490b-e8b1-dba3-32dc-427b89a01e7d.png)
Event Graphにて、BeginPlayでShouOnlyActorComponentsをSelfと設定します。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/ee579d2e-497d-2e1b-888b-6bf1740ecef7.png)
EventGraphにSelfに設定します。これで自分以外のものは写らなくなります。
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/01dc6369-b2c4-7150-fcbb-0eb7d8dd48c6.png)
再びプレイを押します。
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/89f5030a-16da-7bbb-d86d-c48c3b5e59e5.png)
背景がなくなった！わーい！これでキャプチャ完成です。

アイテムメニューっぽくします
-
DataTableで表示するモデルを登録して、選択してるボタンに応じて切り替える機能も作りました。最終成果はこちらになります。
マップにあるアイテムが見えますが、ちゃんと作れば見えない場所にスポーンしましょう。
![ezgif-1-8737e57e24.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/6dfefba4-2965-d7e1-9bfc-75a85fd25958.gif)
手順を書くのはややこしいなので、気になる方は[Github](https://github.com/strangechu/UICapture)にプロジェクトを確認しましょう。

補足Q&A
-
実際の遭遇した問題をQ＆A形式でまとめました。

環境のライティングに影響されてアイテムが明るく／暗くなった！
-
今回キャプチャしたアイテムはマップにスポーンされたのでそうなります。普通のライティングならLightingChannelの調整で影響されないようにしましょう。ポストプロセスなどは実装の方法によって対策します。
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/44913eba-ae60-b2c2-6eb8-7edd1677f81c.png)

ポーズ中で表示したいけど、アイテムのアニメ／テクスチャが動かなくなった！
-
ポーズ中なら大体のTickは失効します。ポーズ中でもTickを有効したい場合はComponentのTickEvenWhenPauseを設定します。マテリアルのTimeノードもIgnorePauseという設定があります。
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/7f095ddb-f3ec-be26-1847-f0186c96b960.png)
![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004980/f00e3d8c-a6d6-f142-ed88-6a6848b2d56c.png)