post-thumb

How to integrate MessagePack C# for Unity?

MessagePack is widely used for games because of its performance. However, it’s not easy to integrate it with Unity due to a lack of documentation and tutorials.

In particular, there are plenty of problems you may encounter when running your app with MessagePack-CSharp library on the IOS device.

Even if you follow the documentation to set up the MessagePack-CSharp library, it might not be easy to make it work.

This tutorial aims to help you smoothly integrate MessagePack-CSharp for Unity.

Get Started

Environment:

  • MacBook Air
  • Unity 2019.3.14f with .NET 4.x
  • MessagePack C# v2.1.165
  • XCode v11.5

Step1

Check out the source codes from GitHub MessagePack C# and place it in your project as below.


Why not install a MessagePack package and related DLL files? Because this way can reduce your time to find and install proper dependent DLL files for MessagePack. Of course, you can manually install them if you want.


Step2

Define the struct or class to be serialized and annotate.


Step3

If you build your game in IL2CPP, you need to run dotnet mpc command to pre-generate codes for your class. Because Unity IL2CPP forbids runtime code generation.

First of all, install dotnet mpc command as below on your mac.

dotnet tool install --global MessagePack.Generator
dotnet new tool-manifest
dotnet tool install MessagePack.Generator

Then run below to test check it work properly.

dotnet mpc -h

Run the command below to generate codes for your class.

dotnet mpc -i Assembly-CSharp.csproj -o <your_output_path>/MessagePackGenerated.cs

Assembly-CSharp.csproj is your C# project. If you use the old version of Unity and select Monno in the Script backend of Unity, you may not need to pre-generate codes. If you use C# in 2.0, your situation may be different from this tutorial.


Step4

Create a MessagePackStatup class as shown below to set up MessagePack lib.

// MessagePackStatu.cs
using MessagePack.Resolvers;
using UnityEngine;
public class MessagePackStatup
{
  static bool serializerRegistered = false;
  [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
  static void Initialize()
  {
  if (!serializerRegistered)
  {
  StaticCompositeResolver.Instance.Register(
    GeneratedResolver.Instance,
    BuiltinResolver.Instance,
    AttributeFormatterResolver.Instance,
    MessagePack.Unity.UnityResolver.Instance,
    PrimitiveObjectResolver.Instance,
    MessagePack.Unity.Extension.UnityBlitWithPrimitiveArrayResolver.Instance,
    StandardResolver.Instance
  );

  var option =     MessagePackSerializerOptions.Standard.WithResolver(StaticCompositeResolver.Instance);
  MessagePackSerializer.DefaultOptions = option;
  serializerRegistered = true;
  }
  }
  #if UNITY_EDITOR
  [UnityEditor.InitializeOnLoadMethod]
  static void EditorInitialize()
  {
  Initialize();
  }
#endif
}

The most important part is you need to define proper Instances to register to MessagePackSerializerOptions as shown below.

StaticCompositeResolver.Instance.Register(
   GeneratedResolver.Instance,
   BuiltinResolver.Instance,
   AttributeFormatterResolver.Instance,
   MessagePack.Unity.UnityResolver.Instance,
   PrimitiveObjectResolver.Instance,
   MessagePack.Unity.Extension.UnityBlitWithPrimitiveArrayResolver.Instance,
   StandardResolver.Instance
 );

What if you define it as below, what will happen?

StaticCompositeResolver.Instance.Register(
      MessagePack.Resolvers.GeneratedResolver.Instance,
      MessagePack.Resolvers.StandardResolver.Instance
 );

You will encounter a problem below when running your game on the IOS device.

FormatterNotRegisteredException: Your Class is not registered in resolver:


Step5

Build and run your game on the IOS device and test.

This’s all.

I hope this tutorial can save your time and successfully integrate MessagePack C# for Unity.

You might be interested in

How to implement Singed Cookies in Unity with CloudFront?

How to reverse engineer C# and Unity3D Games?