UE5.4 PaseモードっぽいのとGameモードの切り替えの実装

# 概要
前回、ローカルのオーディオデバイスを音源をアプリ内に取り込む機能を実装した。※[UE5.4 ローカルで再生中のオーディオ取得および再生①　-対象オーディオデバイス固定-](https://qiita.com/st_akame/items/6ee92970ee6422139a90)
現状、対象のオーディオデバイスはソース内で指定している。
そのため対象デバイスを変更する場合はソース改修が必要であり、あまりにもお粗末。
最適なのはアプリ利用時にUIにて対象のオーディオデバイスを選択すること、そのために今回はUI上からオーディオデバイスを選択できる機能を実装するため、UIを操作するモードを追加する。


# 目的
ローカルのオーディオデバイスを抽出し選択することが出来るUIの実装

# 名称定義
|名称|説明|
|:--:|:--:|
|Main画面|ゲームとしてキャラクターの操作及びストーリーなどをゲームを楽しむ画面|
|Pouse画面|ゲームとしては一時停止状態やコンフィグ設定などの画面|
|UE|Unreal Engine。当環境ではUnrealEngine5.4を指す|
|BP|BluePrintの略|
|Wedgit|UEにおけるUIオブジェクトの総称|


# 要件
## 主画面
* キーボードによるプレイヤーの操作
* マウスによる視線変更
* キー押下によるPouse画面への遷移

## Pouse画面
* マウスによるWedgitの選択
* キャラクターは移動のみ許可
* 主画面のイベントの停止はしない　※BGMなどの再生、時間での描写内容の変更などは継続

# 環境
## バージョン等
|種別|概要|バージョン|
|:--:|:--:|:--:|
|OS|Mac|M1 2020/Sonoma 14.4.1|
|Engine|UnrealEngine|UE5.4.2|
|テンプレート|ThardPorthon| -|
|Plugin| - | -|

# 開発規則
## 命名規則
* 区切り文字としては「 _ 」アンダースコアを利用
* 基本概念として先頭の領域から階層的に下降する
* 最後の領域には用途が容易に認識可能な名称を設定する

**[ファイルタイプ]_[名称]**

# 共通ファイルの修正
## World設定
### デフォルトマップの変更
[1] Project設定を開く
　「Settings」-「Project Settings...」を選択 
[2] 読み込むMapの変更
「Project - Map & Modes」-「Defoult Maps」
　　Editter startup Map : **MAP_PauseUI** 
　　Game defoult Map :**MAP_PauseUI**
[3] Gamemodeの変更
### Gamemodeの変更
[1] world設定を開く
　「Settings」-「world Settings...」を選択 
[2] Gamemodeの変更
　「GameMode」
 　Gamemode Override:**GM_PouseUI**

## 流用用ファイルの複製
アプリ作成時ThirdPersonのテンプレートを利用し、デフォルトで設定されているファイルを本項目向けにコピーする。
|コピー元※「/All/Contents/」は略|コピー先※「/All/Contents/PouseUI/」は略|用途|
|:-:|-:|-:|
|ThirdPerson/BluePrints/BP_ThirdPersonCharacter|BluePrints/BP_Character_PouseUI|ユーザが操作するキャラクターのブループリント|
|ThirdPerson/BluePrints/Inputs/IMC_Defoult|BluePrints/Inputs/IMC_PouseUI|キャラクターに設定するキーマップとアクションの紐付け用ブループリント|
|ThirdPerson/BluePrints/Inputs/Actions/IA_*|BluePrints/Inputs/Actions/IA_*|キーに設定するアクション用ブループリント|


## 必要ファイルの生成
|名前|継承元|用途|
|:-:|:-:|:-:|
|WBP_PouseUI|「User Interfaces」-「Widget BluePrint」|Pause画面用Wedget|
|IA_MainPouseSwitch|Input Action|画面遷移を行うためのアクションイベントの入力を管理する|
|PC_InGame|Player Controler|ゲームモードの管理をキャラクターではなく上位レイ
|HUD_UI|「Object」-「Actor」-「HUD」|Pouse画面を表示させるためHUDクラスのBPを作成する。|
|PG_InGame|GameMode Base|ゲームモードの処理を行うBPを生成する|


### Pause画面用Wedget

[1]「Contents」-「UIs」- 「PouseView」ディレクトリへ移動
[2] 「...add」-「User Interfaces」-「Widget BluePrint」を選択
→Widget BluePrint生成画面が出力
[3] Widget BluePrint生成画面にて下記を選択して生成する。
　Common:**User Widget** 生成するウィジットの継承元を指定する。
[4]生成されたWedgitBluePrintの名前変更
**WBP_PouseUI**

### IA_MainPouseSwitch

[1]「Content Browser」タブより「All」-「COntent」-「PouseUI」-「BluePrints」-「Inputs」-「Actions」へ移動　
[2]「Content Browser」タブより「Add」を押下し「Input」-「Input Action」にてファイル生成
[3]生成されたファイルの名前を「IA_MainPouseSwitch」へ変更

### PC_InGame
ヤにて実施したいため、別途コントローラ用BP|
[1]コンテンツドロワより「PouseUI」ー「BluePrints」-「Inputs」へ移動
[2][Add]を押下し、「BluePrint」-「Player Controler」を選択し「Select」ボタンを押下

### HUD_UI

**HUD**
```
HUD とは、ゲームプレイ中にスクリーン上でオーバーレイ表示されるステータスと情報のことです。
HUD の目的は、 現在のゲームの状態、すなわちスコア、ヘルス値、残り時間などを プレイヤーに知らせることです
```
```
HUD は、スクリーン上にオーバーレイされる要素を表示するための基本クラスです。
ゲーム内でユーザーがコントロールするすべてのプレイヤーは、各自で AHUD クラスのインスタンスを持ち、それらは個々のビューポートに描画されます。
分割スクリーンのマルチプレイヤー ゲームの場合、 複数のビューポートが同じスクリーンを共有しますが、各 HUD は各自のビューポートに描画します。
使用する HUD のタイプやクラスは、 使用しているゲームタイプによって指定されます。
```
[参照元：UE docment](https://dev.epicgames.com/documentation/ja-jp/unreal-engine/user-interfaces-and-huds-in-unreal-engine)

#### 手順
[1]コンテンツドロワより「PouseUI」ー「BluePrints」へ移動
[2][Add]を押下し、「BluePrint」-「All Classes」を展開。「Object」-「Actor」-「HUD」を選択し「Select」ボタンを押下
[3]生成したファイルを **「HUD_UI」** に名称変更

### PG_InGame

[1]コンテンツドロワより「PouseUI」ー「BluePrints」へ移動
[2][Add]を押下し、「BluePrint」-「Game Mode Base」を選択。「Select」ボタンを押下
[3]生成したファイルを **「GM_InGame」** に名称変更


## コピーしたファイルの設定修正

### IMC_PouseUI
#### コピーしたIAとの紐付け
[1]「IMC_PouseUI」を開き「Detalis」タブ-「Mappings」に設定されている「IA_＊」を同名のコピーしたインプットアクションファイルへ差し替える


### BP_Character_PouseUI
#### World設定
[1]「World Settings」-「Game Mode」-「Selected GameMode」-「Defoult PlownClasses 」に **「BP_Character_PouseUI」** を設定

#### キーマッピングBP「IMC_PouseUI」との紐付け
作成したコントローラーマッピングファイルを利用するため、デフォルトのユーザキャラクターの操作マッピングとして設定を行う

[1]「BP_Character_PouseUI」を展開
[2]「Event Ghaph」を開き下記変数を置き換える
「Add Input Mapping」-「Add Mapping Context」-「Mapping Context」： **IMC_PouseUI**

[3]既存の「EnhansedInputAction」関数をIMC_PouseUIにて設定したInputActionへ変更

[4]コンパイルを実行


# 新規ファイルの構築

## Pause画面用Wedget
### Canvas Panelの設置
**【概要】**
* 最上位の状態では複数のオブジェクトを配置できない。
* Pouse画面へ遷移したことを視認しやすいようにする。
* Pouse画面遷移後、メイン画面のオブジェクトを間違えて選択させない。

上記を達成するため、ベースとなるCanvas Panel設置し全画面に敷き詰めてぼかしを入れる。

**【階層構成】**
![スクリーンショット 2024-07-13 14.37.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3711564/1c87656e-787f-194a-b417-dd152b9ba210.png)

**【手順】**
[1] 「Designer」モードへ移動-「Palette」-「Panel」-「Canvas Panel」を「Hierarchy」-「WBP_PouseUI」配下へドラッグ＆ドロップする。

[2]「Palette」-「SPECAL EFFECTS」-「Background Blur」を「Hierarchy」-「WBP_PouseUI」配下へドラッグ＆ドロップする。

[3]「Hierarchy」-「WBP_PouseUI」-「Background Blur」を選択し「Detalis」から下記パラメータを修正
「Slot(Canvas Panel Slot)」-「Anchors」: **Anchors**　※全画面へ拡張
「Application」-「Blur Strengh」：10.0 ※ぼかし効果

[4]「Complie」を押下


## IA_MainPouseSwitch　※デフォルトより変更なし

## IMC_PouseUIの設定
[1]「IMC_PouseUI」を開く
[2]Detalis」タブ-「Mappings」-[+]を押下
[3]生成されたMappingレコードへ下記設定を実施
Mappings: **IA_MainPouseSwitch**
「IA_MainPouseSwitch」-key:**keybord - Tab**
「IA_MainPouseSwitch」-「Trigers」（「+」押下して追加）: **Pressed**
## PC_InGameの設定
![スクリーンショット 2024-07-14 13.39.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3711564/97199b5a-2762-966c-9ff9-27555b29ef15.png)


## HUD_UI の設定
### 追加変数
**PouseUIWidget**
+ VariableType: **WBP_PouseUI**
+ DefaultValue: **-**
+ Private: **true**

**StrPouseVisibility**
+ VariableType: **String**
+ DefaultValue: **Collapsed**
+ Private: **true**

### 追加EventDispaches
**IsPause**
+ VariableName: **IsPause**
+ VariableType: **Boolean**


### ゲーム開始時に折りたたんで表示させる
![スクリーンショット 2024-07-14 13.15.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3711564/14843c58-abcc-e0d8-cb6b-e7d2d3372d42.png)

### Pouse画面遷移イベント発生時の処理
![スクリーンショット 2024-07-14 14.01.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3711564/e6ffe3e7-10a4-cabd-1113-5bfa741df38d.png)

## PC_InGame
### ゲーム起動時はGameモードであることの設定
![スクリーンショット 2024-07-14 14.02.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3711564/eb49c526-a5fc-a710-52e2-a7e73e4a2115.png)

### Pouse画面遷移イベントの受け取り
![スクリーンショット 2024-07-14 14.02.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3711564/52091bdb-04d3-fa8f-25e2-9d36a160a3fa.png)


## World Settings
「Selected GameMode」-「HUD_Class」: **HUD_UI**
「Selected GameMode」-「Player Controller Class」: **PG_InGame**

# 参考
https://zenn.dev/posita33/books/ue5_starter_cpp_and_bp_002/viewer/chap_01-05_bp-ui_widget_game_pause_disp

# GitHubリンク
参考にソースは下記に配置しています。
https://github.com/DevAkame/UE5Leans/tree/main/PaseUI