48.ハイスコアを実装してみよう
😺では今回は前回ページのSaveGameの応用としてハイスコアの機能を実装していきます。
また今回はゲームモードにノードを作っていきます。
今回実装する機能
今回はキューブに弾をヒットさせた回数をスコアとして、今までのゲームプレイで最も高いスコアを保存,表示する機能を実装していきます。
https://youtu.be/PAoS7l6jB-4
プレイするとスコアが高い時にのみ保存されて、ハイスコアとして表示されるのが確認できます。
ハイスコアを実装してみよう
今回はファーストパーソンのプロジェクトを使用します
https://scrapbox.io/files/65c684a9e35bf300255a278a.png
BluePrintsフォルダのなかで、右クリック > ブループリントクラス > SaveGameを選択します。名前はBP_SaveGameとします。
https://scrapbox.io/files/65c684dd779c760025b07ca5.png
BP_SaveGameを開いて変数を作成します。SaveGame_HighScoreという変数名でInteger型を作成します。
https://scrapbox.io/files/65c6850e3cbf9f0024963403.png
コンパイルしておきます。
BP_FirstPersonGameModeを開きます。開き方は以下のように二つありますが、どちらからでも構いません。
https://scrapbox.io/files/65c68551f8821c0026d2f4f7.png
この画面↓が開いた場合はフルブループリントエディタを開くをクリックしてください。
https://scrapbox.io/files/65c68572c35a9d0024819f11.png
BP_FirstPersonGameModeが開かれましたら、まずは以下のノードを作成します。一旦DoesSaveGameExistノードのSlotNameは空のままで。
https://scrapbox.io/files/65c685cee88cef0028fb319f.png
DoesSaveGameExistノードはSaveGameが存在するか(保存されているか)確認するノードでしたね。これらのノードでSaveGameが存在する時としない時で処理を分岐しています。
🐱前回のセーブ機能実装のページではシンプルにするために、SlotNameには直接データ名を記載しましたが今回はString変数を作成してSlotNameに接続します。やってみましょう。
そのままBP_FirstPersonGameModeにSlotNameという名前のString型変数を作成します。
https://scrapbox.io/files/65c686098c9caf00242fbbd8.png
コンパイルしてデフォルト値はSaveDataと入力します。
https://scrapbox.io/files/65c6862d43254c002520e8e9.png
https://scrapbox.io/files/65c6863e1d64320024a80ad1.png
🐱直接「SaveData」と入力していっても構わないのですが、毎回入力するのは面倒ですし入力ミスも防ぐ事ができます。
前回のページとほぼ同様に以下のノードをFalse側から作成します。CreateSaveGameObjectノードを作成してSaveGameClassにBP_SaveGameをセットします。ReturnValueを右クリックから変数へ昇格させて変数名を「BP_SaveGame」にします。
https://scrapbox.io/files/65c686611e56570025e1443e.png
続けてSaveGameGametoSlotからPrintStringで「SaveGameを生成、保存しました。」と入力します。
https://scrapbox.io/files/65c686a8669a980025042938.png
CreateSaveGameObjectでSaveGameを生成して、SaveGameGametoSlotで一旦保存しています。
ではTrue側の処理も前ページのように作成していきます。上画像が前半で下画像が後半のノードです↓LoadGamefromSlot作成して、CastToBP_SaveGame、そこからBP_SaveGameにセットします。GetでSaveGame_HighScoreを取得してPrintStringでテキスト表示します。
https://scrapbox.io/files/65c686d3f3afbf002479626b.png
↑上の画像の続き
https://scrapbox.io/files/65c686e71c9486002542f357.png
LoadGamefromSlotでSaveGameをロードして、SaveGameにあるHighScoreの変数を取得してテキスト表示しています。
プレイしてみましょう。まず最初のプレイでSaveGameを生成,保存します。
https://scrapbox.io/files/65c6874cf8821c0026d2ffda.gif
一旦終了してもう一度プレイしてみるとSaveGameがロードされてHighScoreがロードされます(初期値が0なのでHIGHSCORE : 0)と表示されます。
https://scrapbox.io/files/65c688b8f8821c0026d30632.gif
🐱ここまでは前回までのページとほぼ同じです。ではここからはキューブに弾をヒットさせた分スコアを出力させて、前回のプレイよりスコアがよければハイスコアとして保存します。やってみましょう。
そのままFirstPersonGameModeにCurrentScoreというInteger型の変数を作成します。
https://scrapbox.io/files/65c688cb1c9486002542fb44.png
そのままFirstPersonGameModeに以下のノードを新規追加します。CustomEventと検索してカスタムイベントを作成します。名前をAddScoreとします。そこから++と検索してIncrementIntノードを追加して、GetでCurrentScoreを追加して最後にPrintStringで表示します。
https://scrapbox.io/files/65c6890ebe969b0025ee66fa.png
次に既存のファーストパーソンプロジェクトのフォルダBlueprints > BP_FirstPersonProjectileを開きます。
https://scrapbox.io/files/65c6892e787f3d002432648b.png
このBP_FirstPersonProjectileには以下のノードが既存で用意されています。
https://scrapbox.io/files/65c689591e56570025e150ce.png
このノードは簡単に言うと他のアクタと衝突した時に、そのアクタが物理挙動をするアクタの時にそのアクタに対して衝撃を加えて自身(弾)を削除するというノードです。
要するにこのゲームだと以下のように、配置してあるキューブに弾がヒット場合にのみそのキューブに衝撃を加えて弾を削除するというノードになります。
https://scrapbox.io/files/65c689b501bcc00026855497.gif
このイベントHitノードから繋がる最後のDestroyActorノードから、GetGameModeでゲームモードを取得して、CastToBP_FirstPersonGameMode、カスタムイベントのAddScoreを呼びます。
https://scrapbox.io/files/65c689dc8c9caf00242fccc0.png
GetGameModeとは?
GetGameModeとは現在のゲームモードを取得できるノードです。設定からワールドセッティングを確認してみるとゲームモードオーバーライドにBP_FirstGameModeがセットされています。
https://scrapbox.io/files/65c68a0fe35bf300255a3d68.png
つまりゲームにはBP_FirstPersonGameModeがセットされていてGetGameModeでBP_FirstPersonGameModeが取得されます。
そして作成したノードではCastToでアクセスしてBP_FirstPersonGameMode内で作成したカスタムイベントを読んでいる形になります。
プレイしてみて配置してあるキューブを撃ってみましょう。
キューブを撃つと+1されていきます。
https://scrapbox.io/files/65c68a728fdc16002e071e5a.gif
これをスコアとして保存されたスコアと比較して現在のスコアが大きい場合、HighScoreとして保存していきます。
ではBP_FirstPersonGameModeに戻って、PrintStringから作成していきます。
https://scrapbox.io/files/65c68ab0c7471e0026186acb.png
🐱今回のベストスコアの実装方法は非常にシンプルです。保存されたスコアと現在のスコアを比較して、現在のスコアが大きい場合にそのスコアを上書き保存すれば良いだけです。やってみましょう。
Branchを作成して、「>」と検索してGreater(より大きい)ノードを作成します。CurrentScoreとSaveGame_HighScoreをそれぞれ繋げます。
https://scrapbox.io/files/65c68ad631519b0025c6fcad.png
さらにブランチのTrue側からSaveGame_HighScoreにCurrentScoreをセットします。その後SaveGametoSlotで保存します。
https://scrapbox.io/files/65c68af322b038002459dbe7.png
これで実装は完了です。では解説していきます。
ノード全体解説
https://scrapbox.io/files/65c68b131e56570025e156e0.png
まずキューブに弾を撃ったらCurrentScoreに+1します。CurrentScoreとSaveGame_HighScoreを比較して、現在のスコアとなるCurrentScoreが大きい場合にブランチのtrue側から処理を行います。そしてtrue側でCurrentScoreをSaveGame_HighScoreにセットしてSaveGameを保存という流れになります。
完成! プレイしてみよう
https://youtu.be/PAoS7l6jB-4
プレイするとスコアが高い時にのみ保存されて、ハイスコアとして表示されるのが確認できます。
ちなみにセーブデータを削除したい場合はレベルブループリントに以下のノードを記載する事でできます↓
https://scrapbox.io/files/65c68bbb0c387f0025a75812.png
ちなみにゲームモードではDeleteなどのキーイベントは使えません。なのでキーイベントを実装する時にはゲームモード以外で実装する必要があります。このあたりの仕様も次のページで解説予定です。
実践演習
他ブループリントから変数を取得する
目標:Delete Game in SlotのSlot Nameを直接書き込むのではなく、BP_FirstPersonGameModeで作成した変数SlotNameを使ってみましょう。