前回までのつづきで、UI Navigation 3.0のサンプルからゲーム設定をプレイヤーが好みに調整できる機能を作っていきましょう。

今回はControlsタブのカメラ操作感度(マウス感度やゲームパッドの軸感度)とカメラの軸反転の設定です。

マウス右に動かしたときにカメラは右を向くのか左を向くのかは、
FPSみたく自分が見たいほうに動かすのか、
3人称みたくカメラマンが移動するってイメージかなと
セーブファイル
まず画質等のUEが保存の仕組みを用意してくれているもの(GameUserSettings)以外の
セーブファイルを作ります

ちなみに、C++でいける人は、GameUserSettingsを派生されたカスタムクラスに全部まとめられます。
デドバなどのプロのゲームではそうやってiniファイルに保存されているそうです。
そのうち説明するかもしれませんが、とりあえず初心者向けにBPだけでやりましょう。
丁度それ用の構造体をこのプラグインで用意してくれているので
/All/EngineData/Plugins/UINavigation/Data


この構造体を保存する入れ物を用意します
ただしこれもあとで増やしたり減らしたりを想定してプロジェクト下に複製して「S_GameSettings」と改名しました
そして、それを変数として1つだけ登録したセーブゲームクラスのアセットを作ってあります


変数名も一応それっぽくして
初期値も0だとイマイチなものが多いのでこんな設定にしてあります

ロード処理
まずUINavOptionsMenuの「PreConstruct」イベント(画面を開く前)の最初にファイルからロードします
「Load Settings」という名で関数化しました

中身は
ファイルからロードしてキャストできたら変数にセットします。
「Slot Name」がファイル名になるので後で作るセーブ処理と完全一致させる必要あり。
キャストしてできた「As SG Game Settings」を変数に昇格させましょう。
キャスト失敗したらファイルがないってことで「Create Save Game Object」で初期値のデータを新規作成し同じ変数にセットします
(この時点ではファイルは作られません)


セーブゲームはほかの関数で参照するので関数ローカル変数にしないことがポイントです
これでファイルがなければ初期値、あれば前回保存されている情報が取得できる処理です。
実処理
「Load Settings」の次の「Setup OptionBoxes Index」に、ファイルから取り出した情報で設定メニューをリセットする処理を作ります。

中身は、セーブゲーム内の構造体変数から取り出した情報をメニューのオプションボックスのインデックスにセットする処理です。

たとえば、Sensitivity(入力感度)は実際の情報としては0.1から1という値を使うのでこれが保存されていて、メニュー側は1から10までの表示に対して0から9のインデックスで管理するいわゆるゼロベースです。
0の時0.2、1のとき0.2、2のとき0.3の関係性。
ということは、値が0.3のとき、10倍して約3、四捨五入して正確な整数3にして、それを-1して2のインデックスが得られると。
補足
さきほどの実装時に、しれっと音量とFOVも同様に設定しています。
グラフィックス関連の設定は適用しなかったら保存しないかつファイルと実際の設定が同期しているので放置でかまいませんが、
音量は適用せずにキャンセル終了した場合にもとに戻したいので、
「Update Audio Settings」を呼び出す処理を追加しています。
また、FOVはグラフィック関連の設定といえますが、
GameUserSettingsには保存されないもののようで、「Reset Video Settings」では無視されているのでここでセーブゲームファイルからロードします。
セーブ処理
On Clocked (ApplyButton)適用ボタンのイベントに「Update Other Settings」関数を新規作成してつなぎます

中身は、
Then 0でセーブゲームの構造体を上書き(のちほど説明)して
Then 1で、「Save Game to Slot」でファイルに保存しています。

Windowsでパッケージ化後だとファイルは下記に作成されます。
C:\Users\<ユーザー名>\AppData\Local\<プロジェクト名>\Saved\SaveGames

作成中はプロジェクト配下のSaved/SaveGames内です。
ちなみにグラフィック関連のGameUserSettings.iniはConfigフォルダの中にあります。
実処理
Then 0でやっている構造体の上書き処理は、
Game Settingsから線を伸ばして「Set members」で見つかる構造体の上書きノードを出して、
ノード右クリックから書き換えたいピンを追加(今回は全部追加でOK)して
下図のように保存したい単位に変換して入力します。

たとえば、Sensitivity(入力感度)は1から10までの表示で0から9のインデクスで管理する形で、実際の情報としては0.1から1という値を使います。
ということは、表示が6のとき、そのインデックスが5、それを+1して6にして、10で割ると実際に使う0.6が得られると。
実際のゲーム設定を変える処理
Control関連はプレイヤーが操作するキャラクターと密接な関係にありそうですね。
呼び出し側
ということで処理はプレイヤーキャラクターのブループリントに実装して、設定画面からはそれを呼び出す形とします。
※先にBP_ThirdPersonCharacter側に「Update Game Settings」カスタムイベント定義が必要です。


ここでは簡単のためにBP_ThirdPersonCharacterにキャストしますが、ステージごとにプレイヤーキャラクターが違うとか、タイトル画面でプレイヤーキャラクターをロードしたくないみたいなケースでは、ブループリントインターフェースなどを使うのがよいかと思います。
※当ブログでは8番出口解説でちょこっと使った程度でまだあまり説明していませんが検索してください(^▽^;)
プレイヤーBP側
最初に設定画面から保存したファイルを読み取って変数に保管しています

そのあとは、構造体からデータを取り出してそれぞれ個別の変数に受けとっています。
X軸やY軸反転のフラグは後程実際に使う際に扱いやすいようにプラスマイナス1に変換しています。

最後のFOVは、カメラコンポーネントにSet Field Of View機能があるので、これを実行しています
ウィジェットのほうの「Update Video Settings」関数からは、FOVのコマンド実行する処理を消しています。
あと、音量は本来キャラクターと関係ないですが、ここで設定することで設定画面を開かなくても前回終了時の音量で遊べるようにしています。

美しい作りじゃないので、真面目にやる人は起動時のレベルBPとかでやるべき処理でしょうね(^▽^;)


どちらが適切なのかよくわかりません。2重にやる意味はないと思いますので、どちらか片方は消しましょう。
あとはこの変更イベントをBeginPlay時にも呼んでいます
これによって、設定変更しないでゲーム開始したときやリスポーン時も、前回保存した条件で操作できます。

肝心の受け取った変数たちの使い道ですが、
こんなふうにCamera Inputのところで掛け算の係数としています

インプット信号を条件で反転させたり感度で量調整しています

カメラを動かす軸の入力を受け取った信号そのまま使うか、反転させるか、ちょっと弱めるかっていう感じで、掛け算で軸の情報を加工してからコントローラに渡しているという作りです。
どうせ2つずつ掛けるなら受け取った時点で2つを掛け合わせた変数にまとめる手もありますね
コメント