28.

UE5のセーブ&ロードの基本|SaveGameオブジェクトでのデータ保存と読込

編集

UE5(Unreal Engine 5)のセーブ&ロードは、保存したいデータをSaveGameオブジェクトという専用の入れ物に格納し、それを「スロット」と呼ばれる保存場所に書き出す仕組みです。ゲームを再開したときは、同じスロットからSaveGameオブジェクトを読み込み、中の値を取り出すことで、前回の状態を復元します。この記事では、Blueprintを使った保存と読み込みの基本的な流れと、何を保存すべきか、つまずきやすいポイントを解説します。

この記事の要点
  • セーブ&ロードは「SaveGameオブジェクトにデータを入れ、スロットに保存する」のが基本構造です。
  • 保存は Create Save Game Object →(変数に値を設定)→ Save Game To Slot の順で行います。
  • 読み込みは Does Save Game Exist で存在確認 → Load Game from SlotCast → 値の取得、という流れです。
  • 保存と読み込みではスロット名(Slot Name)とユーザーインデックス(User Index)を一致させる必要があります。
  • HPや進行度などの「数値・状態」は保存できますが、アクターへの参照(実体への参照)はそのまま保存できません

セーブ&ロードの仕組み

UE5のセーブ&ロードは、大きく分けて2つの要素で成り立っています。

構成要素役割
SaveGameオブジェクト保存したいデータ(変数)を入れておくための入れ物。USaveGameクラス(Blueprintでは「SaveGame」クラス)を親に持つBlueprintやC++クラスとして作成します。
スロット(Slot)SaveGameオブジェクトを書き出す保存先の名前。文字列で指定し、同じ名前を使えば上書き、別の名前を使えば別データとして保存できます。

つまり、保存したい値を変数としてSaveGameオブジェクトに持たせ、そのオブジェクトをスロット名で書き出す、というのが基本の考え方です。読み込み時は、スロット名を指定してSaveGameオブジェクトを復元し、中の変数を取り出します。

なお、保存処理を呼び出すノードは GameplayStatics という機能のライブラリに含まれており、Blueprintのどこからでも利用できます。

SaveGameオブジェクトを作成する

まず、保存したいデータを定義するためのSaveGameクラスを用意します。

  1. コンテンツブラウザで右クリックし、「Blueprintクラス」を選択します。
  2. 親クラスとして「SaveGame」を選びます(検索欄に「SaveGame」と入力すると見つけやすいです)。
  3. 作成したBlueprintにわかりやすい名前を付けます(例:BP_MySaveGame)。
  4. そのBlueprintを開き、保存したい値を変数として追加します(例:整数型のPlayerScore、浮動小数点型のPlayerHP など)。

ここで追加した変数が、実際にディスクへ保存される項目になります。保存したい情報をあらかじめ整理して変数化しておくのがポイントです。

保存の手順

ゲーム中の値を保存する基本的な流れは次のとおりです。

  1. Create Save Game Object ノードを配置し、Save Game Class に先ほど作成したクラス(例:BP_MySaveGame)を指定します。これにより、空のSaveGameオブジェクトが新しく生成されます。
  2. 生成されたオブジェクトに対し、保存したい変数へ値を設定します(例:PlayerScore に現在のスコアを代入)。Create Save Game Object の戻り値は既に指定クラスの型になっているため、多くの場合そのまま変数へアクセスできます。
  3. Save Game To Slot ノードを配置し、値を設定したSaveGameオブジェクトを Save Game Object 入力につなぎます。
  4. Slot Name(スロット名、例:SaveSlot01)と User Index(ユーザーインデックス、通常は 0)を指定します。

Save Game To Slot を実行すると、SaveGameオブジェクトの内容が指定スロットへ書き出されます。同じスロット名で再度保存すると、既存のデータは上書きされます。

【保存の流れ(概念)】

Create Save Game Object(Class = BP_MySaveGame)

→ 変数に値を設定(PlayerScore = 現在のスコア など)

→ Save Game To Slot(Slot Name = "SaveSlot01" / User Index = 0)

大量のデータを保存する場合や、ゲームプレイ中に保存して処理の引っかかり(ヒッチ)を避けたい場合は、非同期で保存する Async Save Game To Slot を利用する方法もあります。メニュー画面やポーズ中など、保存タイミングを制御できる場面ではシンプルな Save Game To Slot で十分なことが多いです。詳細な仕様や挙動はバージョンによって異なる場合があるため、必要に応じて公式ドキュメントもあわせて確認してください。

読み込みの手順

保存したデータを読み込む流れは次のとおりです。

  1. Does Save Game Exist ノードで、指定したスロット名・ユーザーインデックスにデータが存在するかを確認します。存在しないスロットをいきなり読み込もうとしても期待した結果にならないため、まず存在確認を行うのが安全です。
  2. 存在する場合に Load Game from Slot ノードを実行し、保存時と同じ Slot Name と User Index を指定します。これにより、ベースとなるSaveGameオブジェクトが復元されます。
  3. Load Game from Slot の戻り値は基本クラス(SaveGame)型のため、Cast(Cast To BP_MySaveGame) で自分が作成したクラスへ変換します。
  4. Castに成功したら、中の変数(PlayerScore など)を取り出し、ゲーム内の状態に反映します。

【読み込みの流れ(概念)】

Does Save Game Exist(Slot Name = "SaveSlot01" / User Index = 0)

→ True のとき Load Game from Slot(同じ Slot Name / User Index)

→ Cast To BP_MySaveGame

→ 変数を取得してゲームに反映(例:スコア表示を更新)

Castに失敗した場合(別のクラスで保存されていた等)は、変数を取り出せません。保存時と読み込み時で同じSaveGameクラスを使うことが前提になります。

何を保存すべきか

セーブデータには、復元したい「状態」を数値や文字列などの値として持たせるのが基本です。一方で、ゲーム実行中にしか存在しない実体(アクターなど)への参照は、そのまま保存しても次回起動時には無効になります。

保存に向く例そのままでは保存に向かない例
  • HPやスコアなどの数値
  • ステージ番号・チェックポイントなどの進行度
  • プレイヤーの座標(位置・回転を値として保存)
  • 所持アイテムの種類や個数(IDや名前で管理)
  • フラグ(イベント達成済みかどうか 等)
  • アクターやコンポーネントへの参照(実体への参照)
  • その場で生成されたオブジェクトのインスタンスそのもの

アクターの状態を保存したい場合は、参照そのものではなく、「位置」「種類を表すID」「残量」などの値に分解して保存し、読み込み時にその値を使って必要なアクターを生成・配置し直す、という設計が一般的です。

つまずきやすいポイント

注意点内容
オブジェクト未生成のまま保存しようとするCreate Save Game Object でオブジェクトを作る前に保存処理へ進むと、保存対象が無く正しく保存できません。読み込み側でも、対象スロットが無い状態で Load Game from Slot を呼ぶと有効な結果になりません。まず Does Save Game Exist で確認しましょう。
スロット名・ユーザーインデックスの不一致保存時と読み込み時で Slot Name や User Index が異なると、保存したデータを読み込めません。スロット名は文字列定数や変数で一元管理し、タイプミスを避けるのがおすすめです。
参照(アクター等)をそのまま保存しようとする前述のとおり、実体への参照は保存に向きません。値(数値・ID・座標など)に置き換えて保存する設計にします。
Castを行わずに値へアクセスしようとするLoad Game from Slot の戻り値は基本クラス型です。自作クラスへ Cast してからでないと、追加した変数にアクセスできません。
容量・プラットフォーム差への配慮不足保存データが大きくなると保存・読み込みに時間がかかることがあります。また、保存先や挙動はプラットフォームによって異なる場合があるため、対象環境での確認が必要です。

なお、保存自体が失敗するケース(権限・容量不足・プラットフォーム固有の制約など)の原因切り分けは、本記事の範囲を超えるため別途扱います。

よくある質問

Q. セーブとロードでスロット名を変えてしまいました。前のデータは消えますか。
A. 別のスロット名で保存しただけなら、元のスロットのデータは残っています。読み込み時に元のスロット名を正しく指定すれば、これまで通り読み込めます。スロット名はデータの「保存先の名前」だと考えるとわかりやすいです。

Q. 複数のセーブスロット(セーブ1、セーブ2…)を作るにはどうすればよいですか。
A. 保存時に指定するスロット名を変えるだけで、複数のデータを別々に保存できます。例えば「SaveSlot01」「SaveSlot02」のように名前を分け、読み込み時に対応する名前を指定します。スロット名を変数として持たせ、UI(セーブ枠の選択など)と連動させると管理しやすくなります。

Q. User Index(ユーザーインデックス)には何を指定すればよいですか。
A. 多くのケースでは 0 のままで問題ありません。User Index は、ローカルの複数ユーザーやプラットフォーム固有のユーザープロファイルを区別したい場合に使う値です。保存と読み込みで同じ値をそろえることだけ意識すれば大丈夫です。

Q. 保存したはずなのに読み込めません。何を確認すべきですか。
A. まず Slot Name と User Index が保存時と一致しているかを確認します。次に、読み込み後に正しいクラスへ Cast できているか、Does Save Game Exist が True を返しているかを確認しましょう。これらが揃っていれば、基本的な読み込みは成立します。

編集
Post Share
子ページ
  1. セーブするボタンを作成する方法
  2. セーブするとセーブファイルの実体がどこに保存されるか
  3. ロードするボタンを作成する方法
同階層のページ
  1. ノード・コンポーネント・関数・クラス一覧
  2. Tips
  3. エラー一覧
  4. ブループリント (Blueprint)
  5. プロジェクト (Project)
  6. レベル (Level)
  7. ウィジェット (Widget)
  8. データテーブル (DataTable)
  9. アセット
  10. アウトライナー
  11. ビュー
  12. レイヤー
  13. レイアウト
  14. ビルド
  15. ライティング
  16. ジオメトリ
  17. アクタ
  18. トランスフォーム
  19. スナップ
  20. ピボット
  21. コンテンツドロワー
  22. コンポーネント
  23. メッシュ
  24. マテリアル
  25. World Composition
  26. World Partition
  27. Unreal Insights
  28. セーブ&ロード

最近更新/作成されたページ