📚

匿名型InstanceをJsonUtility.ToJsonでJson化できない場合の解決策

2024/01/20に公開

はじめに

ある時、下記の様な匿名型を使用して宣言したInstanceをUtility.ToJsonでJson化しようとしたのですが、Json化することができませんでした。エラーも発生せず、空を返しました。なぜ空なのか不明でした。ですが、今回Unity公式のDocumentを確認することで解決することができたので、解決策に関して記事にします。

var requestBody = new 
{
    model = "tts-1",
    voice = "alloy",
    input = text
};

不具合の原因

不具合の原因に関しては、JsonUtility.ToJsonに関するUnityの公式ドキュメントを参考にしました。原文をそのまま引用します。

内部的には、このメソッドは Unity のシリアライザーを使用します。したがって、渡すオブジェクトをシリアライザーでサポートする必要があり、 MonoBehaviour、ScriptableObject や >Serializable 属性が適用されるプレーンなクラスか構造体である必要があります。含めようとするフィールドのタイプはシリアライザーによってサポートされなければなりません。private フィー>ルド、static フィールドや NonSerialized 属性を適用されるフィールドのようなサポートされていないフィールドは無視されます。

https://docs.unity3d.com/ja/2019.4/ScriptReference/JsonUtility.ToJson.html

MonoBehaviour、ScriptableObject や Serializable 属性が適用されるプレーンなクラスか構造体である必要があるとのことです。
匿名型のInstanceはこれに該当しない為、空を返した様です。

解決策

解決策としては、2点あります。
1点目がMonoBehaviour、ScriptableObject や Serializable 属性が適用したクラスを作成して、それをInstanceにすることでJson化できます。
下記の様なコードを書くことで対応できます。

var requestBody = new Property()
{
    model = "tts-1",
    voice = "alloy",
    input = text
};

[System.Serializable]
public class Property
{
    public string model;
    public string voice;
    public string input;
}

ただ、1点目の手法だとJsonを作成する度に、クラスを作成する必要があるのが手間です。

2点目の手法では、Newtonsoft.JsonというPackageを用いる手法です。

https://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@3.2/manual/index.html

こちらのPackageは、'com.unity.nuget.newtonsoft-json'でPackage Managerからimportできます。このパッケージを使用することで、クラスを使用せずしない匿名型のInstanceをJson化できます。

var requestBody = new 
{
    model = "tts-1",
    voice = "alloy",
    input = text
};

string jsonPayload = JsonConvert.SerializeObject(requestBody);

おわりに

今回は、匿名型InstanceをJsonUtility.ToJsonでJson化できない場合の解決策の解決策を紹介しました。
今後も、Unityに関する技術発信をします。良かったと思って頂けたら、Xのフォローや、いいねをお願いします。

Discussion