【UE5】倉庫番を作ろう! ゲームループ・ブラッシュアップ編
はじめに
Unreal Engine (UE) Advent Calendar 2022 その3 16日目の記事です。
最後のパートです。
プロジェクトセットアップ・ゲームプレイ編
メインメニュー・ステージセレクト編
ゲームループ・ブラッシュアップ編(ここ)
ゲームループ編
ここからはメインメニューレベルからゲームプレイレベルまで一方通行だったものをきちんとループできるようにします。更に次のステージに遷移できるようにもしてみます。
ステップ19:ゲームクリアからステージセレクトへ戻る
WBP_GameClearを開いて、Button_StageSelectのOn Clickedイベントを作成し次のように処理を組みます。
そのままP_MainMenuに戻るとメインメニュー画面が表示されてしまうので、Opsitionsを使って「直接ステージセレクトメニューを開く」ことを示します。
次にGM_MainMenuを開きます。Begin PlayのShow Mouse Cursorノードに次のように処理を追加します。
動作確認します。ステージクリア画面を表示して「ステージセレクト」ボタンを押せばステージセレクト画面が表示されればOKです。
しかしステージクリアからステージセレクトに戻ったとき、更に「戻る」ボタンを押してメインメニューに戻ろうとしても何も反応しません。これはGM_MainMenuのOnClicked_ReturnButtonイベントでWBP_MainMenu_RefをValidated Getしたときに「Is Not Valid」に処理が流れてしまっているためです。
この不具合を修正します。GM_MainMenuを開いてOnClicked_ReturnButtonに次のように処理を追加します。
再度、動作確認をして不具合が解消されていればOKです。
ステップ20:次のステージに遷移する
ステージクリア画面の「次へ」ボタンを押すと次のステージに遷移するようにします。
その前にOpen LevelノードのOptionsに指定する文字列やParse OptionのKeyに指定する文字列を定数化しておきます。
定数化した文字列を使っている部分を先程定義したマクロ版に置き換えておきましょう。(画像省略)
WBP_GameClearを開き、Button_NextのOn Clickedイベントを作成します。
Button_NextのOn ClickedイベントにつながるOpen Levelノードにブレークポイントを設置すれば、ステージ名の文字列がどのように変化していくかを覗くことができます。
今回のプロジェクトでのステージ名のようなレベルやデータアセットが「連続した名前」になっていると、「次へ進む」といった処理を作りたいときにとても楽に作ることができます。
動作確認をして「次へ」ボタンを押したとき正しく次のステージが読み込まれてプレイできることが出来ればOKです。
用意したステージを超えて「次へ」を押した場合、エラーメッセージが出力されます。このような用意したステージ数を超えてしまった場合の処理を組んでいきます。
ここでは最後のステージをクリアしたときに「次へ」ボタンを押したときはステージセレクトに戻るようにします。
BP_StageBuilderを開きGet Data Table RowのRow Not Foundピン以降の処理を次のように組みます。
再度、動作確認をします。最後のステージから「次へ」ボタンを押したときにステージセレクトに遷移したらOKです。
ブラッシュアップ編
前回のステップでゲームとして遊ぶための要素は全て追加しました。ここからはあまりゲームの要素とは関係がない部分を実装していきます。
ステップ21:クリアしたステージにCompletedマークを付ける
現状ではステージをクリアしたかが判別できないので、クリアしたステージには「COMPLETED」というマークを付けます。
ステージのクリア状況はゲームを終了しても保持しておく必要があるのでSave Gameクラスを利用することにします。
ゲームを保存して読み込む | Unreal Engine ドキュメント
ステージクリア状況を記録するためのブループリントを作成します。
- 親クラス:Save Game
- 名前:SG_StageCleared
SG_StageClearedを開いて変数を1つ作成します。
まずStageClearedの型を「String」にしておき、型名の右にあるコンテナタイプを「Map」に変更します。次に一番右にある型を「Boolean」型に変更します。
次にWBP_StageButtonを開いて「COMPLETED」というラベルを追加します。パーツを次のように配置します。
ここで注意点ですがボタンパーツは子パーツを1つしか受け入れないのでCanvas Panelを配置できません。TextBlock_Stageを右クリックして「Wrap With...」から「Canvas Panel」を選択すればTextBlock_Stageの親パーツとしてCanvas Panelが自動的に配置されます。
- WBP_StageButton
- [CanvasPanel]
- [TextBlock_Stage]
- Anchor : 中心
- Position X : 0
- Position Y : 0
- Alignment : X & Y=0.5
- Size to Content : チェック入れる
- [TextBlock_Cleared]
- Is Variable:チェック入れる
- Anchor : 中心
- Position X : 40
- Position Y : -20
- Alignment : X & Y=0.5
- Size to Content : CLEARED
- Text : チェック入れる
- Color and Opacity (Hex Linear):FF8000FF
- Font Size:19
- Visibility:Hidden
- Transform Angle:20
- [TextBlock_Stage]
- [CanvasPanel]
色々パーツを配置しましたがCLEAREDラベルがボタンの中心に小さく表示されており、イメージする新しいボタンのレイアウトとはかけ離れてしまっていると思います。ウィジェットブループリントではルートに配置されたパーツは自動的に想定するスクリーンサイズにフィットするようにリサイズされてしまいます。
そこでエディタの右上にある「Fill Screen」と書かれているプルダウンメニューから「Desired」を選択するとボタンが本来表示されるサイズに変化します。
同じくWBP_StageButtonにカスタムイベントを1つ作成します。
次にセーブ時に使う文字列と数値を定数化しておきます。BPML_Constantsを開いて次のようにマクロを組みます。
- 名前:SaveSlotNameIndex
- Compact Node Title:SaveSlotData
次にWBP_StageSelectを開き、Constructイベントに続いて次のように処理を組みます。
ここまででステージクリアデータを読み込むことはできたので次は実際にステージをクリアしたときにセーブデータに書き込みます。
GM_GamePlayを開いてクリア画面表示後にDisable Inputする処理の続きに次のような処理を組みます。
動作確認をします。適当なステージをクリアしたあとにステージセレクトに戻ると「CLEARED」のラベルが貼られている。ゲームを終了&再開してもCLEAREDのラベルが貼られたままであればOKです。
このセーブデータは「.uproject」があるフォルダの「Saved / SaveGames」にあります。
もしセーブデータを削除したいときはSaveGamesフォルダ内にある「.sav」ファイルを直接削除(ゴミ箱行き)してください。エディタが起動中でも削除できます。
ステップ22:ステージセレクトのページ数を増やす
ゲームとしては結構しっかりとしたものになったと思うので、あと4つほどステージを増やしてみます。
WBP_StageSelectを開き、Scroll Boxの子パーツである「Size Box」とその子パーツを全てScroll Box内にコピペします。
次のようにプロパティを変更します。
- WBP_StageSelect
- [CanvasPanel]
- [Scroll Box]
- [Size Box]
- 省略
- [Size Box]
- [Vertical Box]
- [Text]
- Text:STAGE 2
- [Uniform Grid Panel]
- [WBP_StageButton]
- StageName:2-1
- [WBP_StageButton]
- StageName:2-2
- [WBP_StageButton]
- StageName:2-3
- [WBP_StageButton]
- StageName:2-4
- [WBP_StageButton]
- [Text]
- [Vertical Box]
- [Size Box]
- [Scroll Box]
- [CanvasPanel]
更に新しく左右にスクロールするためのボタンパーツを配置します。
- WBP_StageSelect
- [CanvasPanel]
- [Button_Left]
- Anchor : 中心
- Position X : -600
- Alignment : X & Y=0.5
- Size to Content : チェック入れる
- [Text]
- Text:<<
- [Button_Right]
- Anchor : 中心
- Position X : 600
- Alignment : X & Y=0.5
- Size to Content : チェック入れる
- [Text]
- Text:>>
- [Button_Left]
- [CanvasPanel]
後々使うのでScroll Boxの名前を変更しIs Variableにチェックを入れます。
- 名前:ScrollBox_StageList
- Is Variable:チェック入れる
同じくWBP_StageSelectに新しく変数を1つ追加します。
- 名前:TargetScrollOffset
- 型:Float
Button_RightとButton_LeftのOn Clickedイベントを作成します。
次にTickイベントを作成します。
新しく追加した2-1、2-2、2-3、2-4は新しいステージとしてデザインしましょう。ステージがデザインできたあとは忘れずに、DT_StageAssetPathにデータを追加します。
動作確認をして、ステージセレクトで左右のボタンを押すてスクロールすればOKです。クリアしたステージはCLEAREDのラベルが正しく貼られることも更にOKです。
ステップ23:メインメニューとステージセレクトでキー入力を無効化
実はメインメニューやステージセレクトでWASDキーを押すとレベルを動き回れてしまいます。何か不具合が起きてはまずいのでメインメニューとステージセレクトではキーボード操作を無効にします。
WBP_MainMenuを開いてConstructイベントに次のように処理を組みます。
次にWBP_StageSelectを開いてConstructイベントに同じ処理を組みます。
動作確認をしてメインメニューとステージセレクトでWASDキーに何も反応がなければOKです。
しかしSet Input Modeの設定はレベルを跨いでも引き継がれます。ステージセレクトからゲームプレイに移行するとキーボード操作が効きません。ですのでキーボード操作を有効にしたい場合はきちんと設定し直す必要があります。
BP_PlayerControllerを開いてBegin Playイベントの続きに次のような処理を追加します。
再度、動作確認をします。メインメニュー&ステージセレクトはキーボード操作ができず、ゲームプレイではキーボード操作を受け付ければOKです。
おわりに
見た目はとてもシンプルですがゲームとして立派に遊べるものには出来たと思います。
ここからプレイヤーキャラクターをきちんとしたアニメーションがついているものに変更すると、更にゲーム感がアップすると思います(Animation Blueprintとの連携についての知識が必要です)。ブロックも単色ですがきちんとしたモデルを用意したり、テクスチャを貼ってリアルに見せるのも面白いでしょう。音を付けてみるのも良いですね。ブラッシュアップ編ではゲームのクリア状況のみをセーブしていましたが、例えば「クリアするまでの歩数」や「押せるブロックを押した回数」等を記録すると競技感がアップするかもしれません。
この記事がお役に立てば幸いです。
参考資料
記事中に貼っていたリンク先をまとめました。
Unreal Engine の Enhanced Input | Unreal Engine 5.1 ドキュメント
20年オヤジのUnreal Engine 4 TIPS - SEGA TECH Blog
[UE4] 動きに緩急をつけるEaseノードの紹介|株式会社ヒストリア
Paper 2D | Unreal Engine 5.1 ドキュメント
アセットの参照 | Unreal Engine ドキュメント
第007回UE4のアセットの参照方法について、そのロードの違い | CC2の楽屋裏
ハード参照とソフト参照 - おかわりはくまいのアンリアルなメモ
BPの参照連鎖を断つ手法 | 株式会社ヘキサドライブ | HEXADRIVE | ゲーム制作を中心としたコンテンツクリエイト会社
上記以外に参考にした記事&資料です。