はじめに
最近、Unityでのゲームアプリ開発でいろんなアセットを触る機会がありました。
その中で今回は有料アセットの「Easy Save」を使って
簡単なセーブ機能を作ったのでブログにします。
環境
・MacOS
・Unity(2019.3.4f1)
・Easy Save - The Complete Save & Load Tool for Unity(v3.1.4)
Easy Save とは
読んで字の如く、簡単にセーブできるアセット。
機能としては、データの暗号化から、セーブとロードが簡単に行えます。
保存には多くの型に対応していて、
オーディオファイル、プレハブも保存できるみたいです。
その他、オートセーブ機能やクラウドサーバーにデータのUp/Downloadできる機能などがあります。多機能。
ドキュメントはこちら
docs.moodkie.com
やりたいこと
クラスを丸ごと保存、読み込みをしたい。
例えば下記のようなクラスを暗号化して、保存、読み込みをする。
// データ項目 public class Items { public string _appversion; // アプリVer public long _beginUnixTime; // ゲーム開始日 public int _gold; // 所持ゴールド }
やってみる
アセット導入
下記から購入して、Unityプロジェクトへインポート。 assetstore.unity.com
ヒエラルキーを確認すると
「Easy Save 3 Manager」というオブジェクトが勝手に生成されてます。
Unity Editorでシーンを切り替えると毎回勝手に生成されるのが嫌なので、無効にします。
Easy Save設定の変更
Easy SaveのWindowを開きます。
Settingタブの「Auto Add Manager to Scene」のチェックを外します。
これで勝手に生成されないようになりました。
他の設定については、スクリプトから行うので触っていません。
ついでにAuto Save機能はいらないので、AutoSaveタブで
「Save Event」「Load Event」をNoneに設定します。
これで「Easy Save 3 Manager」が勝手に生成されないようになったので、
複数シーンを行き来する場合は自分でインスタンス化する必要があります。
Easy Save 3 Managerの生成
勝手に作成されていた「Easy Save 3 Manager」をプレハブ化。
シーン実行時にプレハブをインスタンス化します。
Test.cs
void Start() { // Easy Save 3 Managerを生成 var prefab = Resources.Load("Prefab/Easy Save 3 Manager") as GameObject; var easySaveManagerObj = Instantiate(prefab); easySaveManagerObj.name = "Easy Save 3 Manager"; }
次にEasy Saveの機能を管理するスクリプトを作成していきます。
Easy Save管理スクリプト作成
SaveUtil.cs
/** * セーブロード処理 */ public class SaveUtils { // 暗号化パス private const string ENCRYPTION_PASS_KEY = "abcdefghi"; // ファイル名 private const string FILE_NAME = "SaveData.es3"; // 設定ファイル public static ES3Settings _es3Setting; // 初期化 public static void Init() { // セーブファイルの暗号化、データ形式の設定 _es3Setting = new ES3Settings() { encryptionType = ES3.EncryptionType.AES, // 暗号化の種類 encryptionPassword = ENCRYPTION_PASS_KEY, // 暗号化Password location = ES3.Location.File, // 保存形式 directory = ES3.Directory.PersistentDataPath, // 保存場所 path = FILE_NAME, // ファイル名(パス) }; } // データを保存する public static void Save<T>(string key, T data) { // 保存 ES3.Save<T>(key, data, _es3Setting); } // データをロードする。 public static T Load<T>(string key) { // keyのデータが存在するか if (!ES3.KeyExists(key, _es3Setting)) { return default; } // ロード return ES3.Load<T>(key, _es3Setting); } // データを削除する public static void Delete(string key) { // キーに該当するファイルが存在しない場合でも例外はスローされない ES3.DeleteKey(key, _es3Setting); } }
原則、このクラスにアクセスして、セーブ、ロードを行うようにします。
クラスを丸ごと引数に渡せば良しなにセーブしてくれています。
設定はUnity Editor Windowからも行えますが、
スクリプトから設定を行うようにしています。(Init関数)
保存、読み込み、削除処理
呼び出し元のスクリプトに処理を追加します。
Test.cs
/** * testシーン管理 */ public class Test : MonoBehaviour { // データ項目 public class Items { public string _appversion; // アプリVer public long _beginUnixTime; // ゲーム開始日 public int _gold; // 所持ゴールド } Items _items; // シーン初期化 void Start() { // Easy Save 3 Managerを生成 var prefab = Resources.Load("Prefab/Easy Save 3 Manager") as GameObject; var easySaveManagerObj = Instantiate(prefab); easySaveManagerObj.name = "Easy Save 3 Manager"; ///////////// 以下追加 ///////////// // 初期化 SaveUtils.Init(); /*********** Save *********/ // 保存内容作成 _items = new Items { _appversion = "1.0.0", _beginUnixTime = 1584425886, _gold = 100 }; // 保存 SaveUtils.Save("Items", _items); /**************************/ /*********** Load *********/ //// ロード、Json化してデバッグログで確認 //_items = SaveUtils.Load<Items>("Items"); //var json = JsonUtility.ToJson(_items); //Debug.Log(json); /**************************/ /*********** Delete *********/ //// キーを指定して削除 //SaveUtils.Delete("Items"); /****************************/ } }
手を抜いて、コメント「Save」「Load」「Delete」箇所のコメントアウトを付け替えて試しています。
セーブするkeyと実体を引数に渡すだけでOK。
Saveの確認
Unity Editor実行後、Easy Saveの設定画面のToolsタブにて
「Open Persistent Data Path」をクリックすると保存先が確認できます。
(ちなみに「Clear Persistent Data Path」はディレクトリ内全てのファイルが削除されますご注意ください)
ファイルが作成されていることが確認できました。
SaveData.es3の中身
v��ܾ8f����r;�{Z#ѩ�r�ꨐC2u�h$I�祐�j#���lZ$��vD�bP���w��%@����M!�4п�}�IlU~(��Q�k�Jि39Pu�zo��/9�ߑ�B�TGk��:����^�".�(����8��5
中身は暗号化されていて、何が保存されているかパッと確認できないので
開発中は暗号化設定はしなくてもいいかもしれません。
Loadの確認
Loadの部分だけ実行されるようにして確認。
デバッグログにJson表示が表示されています。
Deleteの確認
保存先のファイルの中身が空になっていることを確認(ファイル削除はされません)。
以上でセーブ、ロード、データ削除を実装できました。しかし、
実機でエラー
iOS端末で実行してみるとエラーが出ました。(Androidも)
Default settings were not found in scene. Please drag the ES3 default Setting prefab found in Plugins/Easy Save 3/Resources/ES3/into this scene.
Plugins / Easy Save 3 / Resources / ES3 /ES3 Default Settings
このプレハブがシーンにないという旨のエラーのようです。
ソリューション全体に「ES3 Default Settings 」で文字検索をかけてみると、
このプレハブを生成しているところを発見。
原因はEasy Saveアセットの下記スクリプト
Assets/Plugins/Easy Save 3/Scripts/Settings/ES3Settings.cs
146行目〜 internal static void LoadDefaults() { #if !UNITY_EDITOR これ→ //var go = Resources.Load<GameObject>("ES3/ES3 Default Settings"); これ→ var go = GameObject.Find("ES3 Default Settings"); if(go == null) { Debug.LogError("Default settings were not found in scene. Please drag the ES3 Default Settings prefab found in Plugins/Easy Save 3/Resources/ES3/ into this scene."); return; } #else var go = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(UnityEditor.AssetDatabase.GetAssetPath(Resources.Load<GameObject>("ES3/ES3 Default Settings"))); #endif var component = go.GetComponent<ES3DefaultSettings>(); if(component == null) return; _defaults = component.settings; }
これは・・・テストコードが残ってた?
> これ→ var go = Resources.Load<GameObject>("ES3/ES3 Default Settings"); > これ→ //var go = GameObject.Find("ES3 Default Settings");
上記コメントアウトを入れ替えて実行してみたところ、無事正常に動作しました。
最後に
今回、Easy Saveでの実装は最低限の内容になっていますが、
他にも様々な便利機能があるので追々検証してみたいと思います。