ARPG開発 007 セーブとロード

キャラクターのステータスとインベントリをセーブするシステムを実装。

Struct_ItemDataの編集

Struct_ItemDataのItem Nameのデフォルト値をEmptyにします。
Load時にEmptyは対象外にしたいからです。

構造体を作成

セーブする項目は構造体にまとめます。
コンテンツブラウザで右クリックしてブループリント > 構造体を選択。
名前はStruct_PlayerDataにしました。経験値やHPや攻撃力など、プレイヤーのセーブしたいステータスをまとめます。
【Location】
ゲーム開始時に読み込まれますので、Locationの座標は入力が必要です。
【インベントリ】
まず1つめのスロットなら、Slot_0という名前で型はStruct Item Data。
これをSlot_14まで作成。
【スロット拡張アイテム】
NewSlotCountという名前で型はInteger。デフォルト値は1です。

セーブデータ用のブループリント作成

コンテンツブラウザで右クリックしてブループリント クラスを選択し、親はSaveGameにする。
名前はBP_SaveDataにしました。

BP_SaveDataの編集

変数を追加することでセーブしたいデータを追加できます。

変数を追加します。
名前はPlayerDataで型はStruct Player Data。

ゲームインスタンスの作成

コンテンツブラウザで右クリックしてブループリント クラスを選択し、親はGameInstanceにする。
名前はBP_MyGameInstanceにしました。

BP_MyGameInstanceの編集

変数を追加します。名前はSaveData、型はBP Save Data (オブジェクト参照)。

ノードを組む

イベント Initを配置して線を伸ばしてDoes Save Game Existを作成。これは既にセーブデータが存在するか確認するものです。そのSlot Nameから線を伸ばして変数へ昇格。名前をSaveSlotNameにして、コンパイルしてからデフォルト値をSaveData1にします。

Return Valueから線を伸ばしてブランチを配置。
ブランチのFalseから線を伸ばしてCreate Save Game Objectを配置。Save Game ClassはBP Save Dataにします。
Return Valueから線を伸ばして変数へ昇格。名前をSaveGameRefにします。

関数を追加します。名前はSavePlayerData。

ノードを組む

変数SaveGameRefをGetして線を伸ばして、Set Player Dataを配置。Player Dataから線を伸ばしてSave Player Dataに繋げる。主線も繋ぐ。
セットから線を伸ばしてSave Game to Slotを配置。
Save Game ObjectにはSave Game Refを繋ぐ。
Slot Nameには変数SaveSlotNameをGetして繋ぐ。

関数を追加します。名前はLoadPlayerData。

ノードを組む

Load Player Dataから線を伸ばしてLoad Game from Slotを配置。Slot Nameには変数SaveSlotNameをGetして繋ぐ。
Load Game from Slotから線を伸ばしてCast To BP_SaveDataを配置。
変数SaveGameRefをSetして、Cast To BP_SaveDataから2本の線で繋ぐ。
セットの右下から線を伸ばしてPlayerDataを取得
関数LoadPlayerDataを選択し、詳細のアウトプットを+して追加。
出現したリターンノードPlayerDataから線を伸ばして入れる。アウトプットのBooleanの方は削除してください。
セットリターンノードも繋げる。
編集 > プロジェクト設定 > プロジェクト > マップ&モードのゲームインスタンスクラスにBP_MyGameInstanceを設定しておきます。

UI_Inventoryの編集

関数を追加、名前はLoadInventorySlotにします。
ノードを組む

LoadInventorySlotから線を伸ばしてCast To BP_MyGameInstanceを配置。ObjectからはGet Game Instance
As My GameInstanceから線を伸ばして変数へ昇格。名前はMyGameInstanceにします。
セットからLoad Player Dataを配置。ターゲットセットと繋ぐ。
変数PlayerDataをSetして、Load Player Dataから2本の線を繋ぐ。右下のピンで右クリックして構造体ピンを分割
配列を作成を配置して[14]までピンを追加する。そこにSlot 0 Item DataSlot 14 Item Dataまで繋ぐ。
セットの実行ピンからFor Each Loopを配置。その中のArray配列を作成Arrayを繋ぐ。
最後にUpdate Inventory Slotを配置。
【スロット拡張アイテム】
New Slot Countをセットして、For Each LoopのCompletedから繋げる。線を伸ばして整数型でスイッチを配置。SelectionにはNew Slot Countを繋ぐ。
整数型でスイッチを配置のピンを追加して3まで表示。
New Slot Countはデフォルト値が1であり枠は5。拡張アイテムを使うと枠が10になった後、New Slot Countは2になります。
整数型でスイッチを配置の2から線を伸ばしてSetVisivilityを配置。ターゲットはGrid 1。In Visibilityを表示にする。
整数型でスイッチを配置の3から線を伸ばしてSetVisivilityを配置。ターゲットはGrid 1とGrid 2。In Visibilityを表示にする。
【空のアイテムを対象外にする処理】
For Each LoopArray Elementから線を伸ばしてStruct_ItemDataを分解。その中のItem Nameから線を伸ばしてEqual Exactly (Text)を配置。その左下からはTo Text (String)を配置し、TextBoxにはEmptyと入力。
Equal Exactly (Text)の右から線を伸ばしてブランチを配置。For Each Loopから繋ぎ、Update Inventory Slotへ繋ぐ。
これでItem NameがEmptyになっているものを除外できます。

プレイヤーブループリントの編集

ロード
ノードを組む

イベント BeginPlayのから続くノードの最後から線を伸ばしてCast To MyGameInstanceを配置。※For Each Loopから続いていた場合は実行ピンではなくCompletedから繋ぐこと。
ObjectにはGet Game Instanceを配置して繋ぐ。
As My GameInstanceから線を伸ばして変数へ昇格。名前はMyGameInstanceにします。
セットからLoad Player Dataを配置。ターゲットセットと繋ぐ。
変数PlayerDataをSetして、Load Player Dataから2本の線を繋ぐ。右下のピンで右クリックして構造体ピンを分割
セットから線を伸ばしてSet Actor Locationを配置。その中のターゲットから線を伸ばしてGet Player Characterを配置。
New LocationLocationも繋ぐ。
最後の先ほど作成したLoad Inventory Slotを繋ぐ。
セーブ

セーブメニューを作成していないので、0キーでセーブするようにします。

ノードを組む

キーボードイベント0のPressedから線を伸ばしてPlay Sound 2Dを配置。セーブした時に音を鳴らすためです。その中のSoundで音を指定。
そこから線を伸ばして「状況に合わせた表示」のチェックを外してからSave Player Dataを配置。
ターゲットには変数MyGameInstanceをGetして繋げます。
Player Dataで右クリックして構造体ピンを分割
Player Data LocationにはGet Actor Locationを配置して繋ぎます。
その他の項目は変数をGetして繋ぐ。まだ作っていない変数は追加しておく。
Slot_*は変数Inventory WidgetをGetしてSlot_0を取得、そこから線を伸ばしてItem Dataを取得。これをSlot_14まで。
New Slot CountもGetして繋げる。
セーブデータの削除
2キーでデータを削除するようにします。
ノードを組む

キーボードイベント2のPressedから線を伸ばしてDelete Game in Slotを配置。
変数MyGameInstanceをGetして線を伸ばしてSave Slot Nameを取得。そこからSlot Nameに繋げる。

難しいっ!

自分で考えて調整できるようになってきたものの、まだまだ理解が浅いと感じます。
ステータスとインベントリのセーブとロードはできましたが、装備中の武器のセーブとロードはできないまま。
そもそも装備とインベントリの仕様をしっかり考えていなかったのが問題でした。

コメント

  1. Ellsworth Ribar より:

    Excellent write-up

タイトルとURLをコピーしました