UnityのセーブデータにMessagePack-CSharpを利用してみる
はじめに
前回はUnityでMasterMemoryを使ってみました。 今回はこのMasterMemoryに付属してくるMessagePack-CSharpを セーブデータの保存に利用してみます。
- Unity: 2019.2.1f1
- MessagePack-CSharp: Ver 1.7.3.5
MessagePack-CSharpを使う
前回の記事のとおりに実行していれば、MessagePack-CSharpを利用するのに必要なコード生成の処理が書かれています。
試しにスキルレベルを保存するコードを書いてみます。
SaveData.cs
に次のように。
using System.Collections.Generic;
using MessagePack;
[MessagePackObject]
public class SaveData {
[Key (0)]
public List<int> SkillLevels { get; set; }
public SaveData (List<int> skillLevels) {
SkillLevels = skillLevels;
}
}
SaveDataManager.cs
に次のように。
using System.Collections.Generic;
using System.IO;
using MessagePack;
using UnityEngine;
public class SaveDataManager {
private static SaveDataManager _instance = new SaveDataManager ();
public static SaveDataManager Instance => _instance;
private SaveData _saveData;
private void CreateNewSavedata () {
_saveData = new SaveData (new List<int> { 1, 1, 1, 2 });
}
public void Load (string saveFilename) {
var saveDirectory = $"{Application.dataPath}/SaveData";
var filePath = $"{saveDirectory}/{saveFilename}";
try {
using (var fs = new FileStream (filePath, FileMode.Open, FileAccess.Read)) {
byte[] bytes = new byte[fs.Length];
fs.Read (bytes, 0, bytes.Length);
_saveData = MessagePackSerializer
.Deserialize<SaveData> (bytes);
}
} catch {
CreateNewSavedata ();
}
}
public void SaveSkillLevels (string saveFilename, List<int> skillLevels) {
_saveData.SkillLevels = skillLevels;
var bytes = MessagePackSerializer.Serialize (_saveData);
var saveDirectory = $"{Application.dataPath}/SaveData";
Directory.CreateDirectory (saveDirectory);
var filePath = $"{saveDirectory}/{saveFilename}";
using (var fs = new FileStream (filePath, FileMode.Create)) {
fs.Write (bytes, 0, bytes.Length);
}
}
public IReadOnlyList<int> SkillLevels => _saveData.SkillLevels;
}
Test.cs
を次のようにします。
using System.Linq;
using UnityEngine;
public class Test : MonoBehaviour {
void Start () {
var db = MasterDataDB.DB;
var saveDataManager = SaveDataManager.Instance;
saveDataManager.Load ("save-file-0");
var skillLevels = saveDataManager.SkillLevels;
foreach (var skill in db.SkillTable.All) {
Debug.Log ($"Skill Name: {skill.SkillName}");
var lv = skillLevels[skill.SkillID];
Debug.Log ($"Skill Lv: {lv}");
var parameter = db.SkillParameterTable
.FindBySkillIDAndSkillLv ((skill.SkillID, lv));
Debug.Log ($"Skill Damage: {parameter.Damage}");
}
var newLevels = skillLevels.Select (lv => {
if (lv >= 9) return lv;
return lv + 1;
}).ToList ();
saveDataManager.SaveSkillLevels ("save-file-0", newLevels);
}
}
「MasterMemory > CodeGenerate」を実行します。
実行するたびにレベルが上っていきます。
バイナリファイルにデータが書き込まれています。
おわりに
バイナリファイルにシリアライズすることでセーブデータの保存ができました。 今回作ったセーブデータマネージャがあまりにも適当なので もっとしっかりしたセーブデータ管理システムを作りたいです。