ふりかえり
前回はアーティファクトにS〜Cランクのレアリティを追加し、ガチャで高ランクが出にくくなるように調整しました!
セーブを実装!
今回はいよいよ「セーブ機能」を実装します!
これまでのゲームでは、アプリを閉じると進行状況が初期化されてしまい、毎回最初からプレイし直しになっていました。
これではゲームとして成立しないので、G(ゴールド)とダイヤの所持データをセーブ・ロードできるようにしていきます。
Easy Save
今回、ゲームのセーブ機能を実装するにあたり、Easy SaveというUnity Assetを使用します。

Easy Saveは、Unity向けの高機能かつ柔軟なセーブ・ロードシステムで、コードからはもちろん、PlayMakerなどのビジュアルスクリプトでも簡単に扱うことができます。
Unityには標準でPlayerPrefsというセーブ機能がありますが、以下のような制限があります:
- 保存できるデータ型が限られている(int、float、stringのみ)
- 保存先が端末内の分かりやすい場所にあり、ユーザーから容易にアクセスできてしまう
- データを一括で保存・管理することができない
- 大容量データの保存には不向き
これに対してEasy Saveは、多様なデータ型の保存、暗号化、圧縮、ファイル操作の柔軟性など、セーブ処理を包括的にサポートしており、複雑なセーブ・ロード処理も簡単に実装できます。
スクリプトの変更
Save Manager.cs
このスクリプトでは、Easy Save 3(ES3)を使って、ゲームデータの保存と読み込みを行います。
アプリを閉じるタイミングで自動的にセーブされるようにもしてあります
また、データの読み込みはゲーム開始時に行います
using UnityEngine; public class SaveManager : MonoBehaviour { [Header("参照")] public PlayerManager playerManager; [Header("セーブ設定")] public string saveFileName = "GameData.es3"; // セーブファイル名 void Start() { // ゲーム開始時にデータをロード LoadGameData(); } // ゲームデータをセーブ public void SaveGameData() { if (playerManager == null || playerManager.player == null) return; try { // G(ゴールド)とダイヤをセーブ ES3.Save("PlayerGold", playerManager.player.gold, saveFileName); ES3.Save("PlayerDiamond", playerManager.player.diamond, saveFileName); Debug.Log("ゲームデータをセーブしました"); } catch (System.Exception e) { Debug.LogError($"セーブエラー: {e.Message}"); } } // ゲームデータをロード public void LoadGameData() { if (playerManager == null || playerManager.player == null) return; try { // G(ゴールド)とダイヤをロード if (ES3.KeyExists("PlayerGold", saveFileName)) { playerManager.player.gold = ES3.Load<int>("PlayerGold", saveFileName); Debug.Log($"セーブデータからゴールドをロード: {playerManager.player.gold}"); } if (ES3.KeyExists("PlayerDiamond", saveFileName)) { playerManager.player.diamond = ES3.Load<int>("PlayerDiamond", saveFileName); Debug.Log($"セーブデータからダイヤをロード: {playerManager.player.diamond}"); } Debug.Log("ゲームデータをロードしました"); } catch (System.Exception e) { Debug.LogError($"ロードエラー: {e.Message}"); } } // セーブデータを削除 public void DeleteSaveData() { try { ES3.DeleteFile(saveFileName); Debug.Log("セーブデータを削除しました"); } catch (System.Exception e) { Debug.LogError($"セーブデータ削除エラー: {e.Message}"); } } // セーブデータが存在するかチェック public bool HasSaveData() { return ES3.FileExists(saveFileName); } // アプリケーション終了時にセーブ void OnApplicationPause(bool pauseStatus) { if (pauseStatus) { SaveGameData(); } } // アプリケーション終了時にセーブ void OnApplicationQuit() { SaveGameData(); DebugSaveData(); } // SaveManagerにデバッグ用メソッドを追加 public void DebugSaveData() { Debug.Log($"現在のゴールド: {playerManager.player.gold}"); Debug.Log($"現在のダイヤ: {playerManager.player.diamond}"); Debug.Log($"セーブファイル存在: {HasSaveData()}"); } // PlayerDataを初期化(セーブデータを考慮) public PlayerData InitializePlayerData() { PlayerData playerData = new PlayerData { name = "勇者", level = 1, baseMaxHP = 100, // 基礎HP baseAttack = 10, // 基礎攻撃力 baseDefense = 0, // 基礎防御力 baseCriticalRate = 0.1f, // 基礎会心率 baseCriticalDamageMultiplier = 2.0f, // 基礎会心ダメージ倍率 currentHP = 100, exp = 0, // 初期経験値 gold = 0, // 初期お金 expToNextLevel = 10, // 次のレベルに必要な経験値 // G強化ステータスとアーティファクトステータスは初期値0のまま gPowerUpHP = 0, gPowerUpAttack = 0, gPowerUpDefense = 0, gPowerUpCriticalRate = 0f, gPowerUpCriticalDamage = 0f, artifactPowerUpHP = 0, artifactPowerUpAttack = 0, artifactPowerUpDefense = 0, artifactPowerUpCriticalRate = 0f, artifactPowerUpCriticalDamage = 0f }; // セーブデータがある場合はロード try { if (ES3.KeyExists("PlayerGold", saveFileName)) { playerData.gold = ES3.Load<int>("PlayerGold", saveFileName); Debug.Log($"セーブデータからゴールドをロード: {playerData.gold}"); } if (ES3.KeyExists("PlayerDiamond", saveFileName)) { playerData.diamond = ES3.Load<int>("PlayerDiamond", saveFileName); Debug.Log($"セーブデータからダイヤをロード: {playerData.diamond}"); } Debug.Log("PlayerDataの初期化が完了しました"); } catch (System.Exception e) { Debug.LogError($"PlayerData初期化エラー: {e.Message}"); } return playerData; } }
PlayerManager.cs
public void GainRewards(int exp, int gold) { player.exp += exp; player.gold += gold; // 5%の確率でダイヤを獲得 bool gotDiamond = false; if (Random.value < 1f) { player.diamond += 100; gotDiamond = true; } // バトルログに追加 if (battleLogManager != null) { battleLogManager.AddRewardLog(exp, gold); if (gotDiamond) { battleLogManager.AddLog("ダイヤを1個獲得した!", Color.cyan); } } Debug.Log($"{player.name}は{exp}EXPと{gold}Gを獲得しました!"); if (gotDiamond) { Debug.Log($"{player.name}はダイヤを1個獲得しました!"); } // レベルアップのチェック CheckLevelUp(); // 報酬獲得後にセーブ if (saveManager != null) { saveManager.SaveGameData(); } }
報酬を受け取ったとき、ダイヤを獲得したときなどにもセーブを行うようにします。
今後は、Gやダイヤが増減するすべてのタイミングで SaveGameData() を呼び出すようにしていきます。
例:
- 強化でGを消費(PowerUpManager)
- ガチャやアーティファクト強化でダイヤを消費(ArtifactManager)など
Unityでの設定
- Hierarchyに新しいGameObjectを作成(例:SaveManager)
- 作成したGameObjectにSaveManager.csをアタッチ
- PlayerManagerの参照をInspectorでセット

動作確認
- モンスターを倒してGとダイヤを獲得
- ガチャや強化でG・ダイヤを消費
- アプリを終了 → 再起動
- ⇒ しっかりセーブデータが読み込まれ、所持数が引き継がれていました!

まとめ
今回はゲームにとって重要な「セーブ機能」の第一歩として、Gとダイヤの保存を実装しました!
いよいよゲームらしくなってきましたね!
次回予告
次回は、さらにプレイヤーのステータス、進行ステージ、強化状態、アーティファクト所持情報など、すべてのデータをセーブできるようにしていきます!
お楽しみに!