※ これは 2022/01/21 時点の Unity 2021.2.8f1、MessagePack for C# v2.3.85 の情報です
最新版では動作が異なる可能性がありますのでご注意ください
前回、MessagePack for C# を使用できるように準備をしたので、さっそく使ってみる
とりあえず、Unity で使う上でほぼ必須となる AOT コンパイラ対応用のコード生成とシリアライザの動作確認をする
スポンサードリンク
まずはシリアライズするデータクラス SaveData
の入れ物を用意
using MessagePack; using System; namespace MatatabiUx.Common { /// <summary> /// セーブデータ /// </summary> [MessagePackObject] [Serializable] public partial class SaveData { /// <summary> /// ID /// </summary> /// <value></value> [Key(0)] public int Id { get; protected set; } = default; /// <summary> /// 保存日時 /// </summary> /// <value></value> [Key(1)] public DateTimeOffset Timestamp { get; protected set; } = default; /// <summary> /// 空データフラグ /// </summary> [IgnoreMember] public bool IsEmpty => this.Id == default; public SaveData() { } [SerializationConstructor] public SaveData(int id, DateTimeOffset timestamp) { this.Id = id; this.Timestamp = timestamp; } } }
クラスにはシリアライズ対象の目印として [MessagePackObject]
と [Serializable]
の属性を付与し、シリアライズ対象プロパティには [Key]
属性、対象外のものには [IgnoreMember]
をつける
[Key]
属性はインデックス番号をつけず、デフォルトのプロパティ名をキーにしてもらうこともできるが、インデックス番号で明示して上げた方がデータが圧縮できるしいろいろ効率がいいのでインデックス番号をつけた
インデックス番号を付ける場合、インデックス番号順の引数をもつコンストラクタを用意し、[SerializationConstructor]
をつける
とりあえずこれで入れ物の準備が完了
次にコード生成、これをやっておかないと Unity で作ったアプリを iOS 実機上で動かすとエラーで止まったりするのでまずい
UnityEditor のメニューから [Window] - [MessagePack] - [CodeGenerator] が表示されるので、input path
に対象の .csproj ファイル、output filepath
に出力するシリアライザソースファイル名を指定する
パスは Assets
ディレクトリから見た相対パスで指定可能で、input path
には SaveData
のデータクラスが参照しそうなプロジェクトを全部指定する(基本は ../Assembly-CSharp.csproj
だけでよいが今回は ../MatatabiUx.Common.csproj
も念のため半角空白で区切って追加)
あとは Generate
ボタン押下・・・しばらく待つと
こんな感じで UnityEditor のログが出力されて生成完了
さて、試しにシリアライズを下記のテストコードで試してみる
using MatatabiUx.Common; using MessagePack; using UnityEngine; public class Test : MonoBehaviour { public void Awake() { // シリアライザの初期設定 MessagePack.Resolvers.StaticCompositeResolver.Instance.Register( MessagePack.Resolvers.GeneratedResolver.Instance, // コード生成した型解決クラス MessagePack.Unity.UnityResolver.Instance, MessagePack.Unity.Extension.UnityBlitWithPrimitiveArrayResolver.Instance, MessagePack.Resolvers.StandardResolver.Instance ); var option = MessagePack.MessagePackSerializerOptions.Standard .WithCompression(MessagePack.MessagePackCompression.Lz4BlockArray) // LZ4 圧縮利用 .WithResolver(MessagePack.Resolvers.StaticCompositeResolver.Instance); MessagePack.MessagePackSerializer.DefaultOptions = option; } public void Start() { // シリアライズしたものをデシリアライズしてみる var data = new SaveData(1, System.DateTimeOffset.Now); var serialized = MessagePackSerializer.Serialize(data); var deserialized = MessagePackSerializer.Deserialize<SaveData>(serialized); UnityEngine.Debug.Log( $"Id={deserialized.Id}, Timestamp={deserialized.Timestamp}"); } }
シリアライザを使えるようにするおまじないコードと、シリアライズ→デシリアライズを試すコードが入っているだけ
これを適当な GameObject にアタッチしてお試し実行