ふりかえり
前回はアーティファクトに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とダイヤの保存を実装しました!
いよいよゲームらしくなってきましたね!
次回予告
次回は、さらにプレイヤーのステータス、進行ステージ、強化状態、アーティファクト所持情報など、すべてのデータをセーブできるようにしていきます!
お楽しみに!

