LoginSignup
5
2

UnityでMessagePack-CSharpのSourceGeneratorを使ってみる

Last updated at Posted at 2024-01-20

はじめに

今まで MessagePack-CSharp を IL2CPP 環境下で動かすには事前のコード生成が必要でなかなか面倒だったんですが、 v2.6.100 からは SourceGenerator に対応するため、コード生成用コマンドを打つ必要がなくなるようです。

インストール

ダウンロード

Releases の v2.6.100 以降の最新版を探し、以下のファイルをダウンロードします。

  • MessagePack.Unity.unitypackage
  • MessagePack.SourceGenerator.Unity.zip

2024/1/20時点では v2.6.100 は正式リリースされていないようです。

本体インストール

MessagePack.Unity.unitypackage を開き、Unity に取り込みます。

PackageManagerで管理したい場合

Plugins フォルダ内の dll だけを取り込み、 packages.json に以下を追記します。

"com.neuecc.messagepack": "https://github.com/neuecc/MessagePack-CSharp.git?path=src/MessagePack.UnityClient/Assets/Scripts/MessagePack#v2.6.100-alpha"

#以降に指定するバージョンは最新に合わせてください。

SourceGenerator インストール

MessagePack.SourceGenerator.Unity.zip を解凍して出てきたすべての dll を Unity に取り込み、以下の設定を行います。

  • すべてのプラットフォーム選択を外す image.png
  • RoslynAnalyzer ラベルを付与する image.png

初期化処理追加

生成された Resolver をデフォルトの呼び出し時に使用するように設定します。
※現時点では Resolver が生成されていないのでエラーが出ます。

using MessagePack;
using UnityEngine;

public static class Startup
{
#if UNITY_EDITOR
    [UnityEditor.InitializeOnLoadMethod]
#endif
    [RuntimeInitializeOnLoadMethod]
    private static void Initialize()
    {
        MessagePackSerializer.DefaultOptions = MessagePackSerializerOptions.Standard
            .WithResolver(GeneratedMessagePackResolver.InstanceWithStandardAotResolver);
    }
}

動作確認

以下のクラスを定義してみます。

using MessagePack;
using UnityEngine;

[MessagePackObject]
public class SampleObject
{
    [Key(0)] public string Name { get; set; }
    [Key(1)] public Vector3 Position { get; set; }
}

すると、 MessagePack.GeneratedMessagePackResolver クラスが自動生成されます。
なお、Rider を使っている場合、生成コードの中身を見ることもできます。
image.png

以下のコードで動作確認します。

using System;
using MessagePack;
using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    [SerializeField] private Text text;

    private void Start()
    {
        try
        {
            var obj = new SampleObject
            {
                Name = "Sample",
                Position = new Vector3(1, 3, 5),
            };
        
            var serialized = MessagePackSerializer.Serialize(obj);
            text.text = "シリアライズされたデータ\n" + BitConverter.ToString(serialized);
        
            var deserialized = MessagePackSerializer.Deserialize<SampleObject>(serialized);
            text.text += "\n\nデシリアライズされたデータ\n" + deserialized.Name + deserialized.Position;
        }
        catch (Exception e)
        {
            text.text = e.ToString();
        }
    }
}

エディタ上ではIL生成が動いてテストにならないためIL2CPPでビルドして動作を確認すると、以下のように想定通りの出力が表示されました。

image.png

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2