Version: 2020.2
言語: 日本語
スクリプトのシリアル化に関連するエラー
スクリプトのコンパイル

JSON 形式へのシリアル化

JsonUtility クラスを使用して、Unity オブジェクトと JSON 形式間で変換できます。 例えば、JSON シリアライゼーションを使用してウェブサービスとやり取りしたり、データをテキストベースの形式に簡単にパックしたりアンパックしたりすることができます。

JSON 形式とのシリアル化では、“構造化された” JSON という概念を使用しています。つまり、クラスや構造体を作成して、JSON データに保存したい変数を記述します。以下はその例です。

[Serializable]
public class MyClass
{
    public int level;
    public float timeElapsed;
    public string playerName;
}

これは、3 つの変数 (leveltimeElapsedplayerName) を含む簡易な C# クラスを定義し、JSON シリアライザーで動作するように、Serializable 属性でマークしています。クラスのインスタンスの作成は、以下のように行います。

MyClass myObject = new MyClass();
myObject.level = 1;
myObject.timeElapsed = 47.5f;
myObject.playerName = "Dr Charles Francis";

その後、JsonUtility.ToJson メソッドを使って、JSON 形式にシリアライズ (変換) します。

string json = JsonUtility.ToJson(myObject);
// json には以下の内容が含まれています。'{"level":1,"timeElapsed":47.5,"playerName":"Dr Charles Francis"}'

JSON をオブジェクトに戻すには、JsonUtility.FromJson を使用します。

myObject = JsonUtility.FromJson<MyClass>(json);

これにより、MyClass の新しいインスタンスが作成され、JSON データを使用して値が設定されます。JSON データに MyClass のフィールドにマップされていない値が含まれている場合、シリアライザーはこれらの値を無視します。JSON データに MyClass のフィールドの値が含まれていない場合、シリアライザーは、これらのフィールドの構築された値を、返されたオブジェクトに残します。

JSON シリアライザーは、現在、構造化されていない JSON の操作をサポートしていません。つまり、キーと値のペアからなる任意のツリーとして JSON を走査、編集することができます。これを行う必要がある場合は、より完全な機能を備えた JSON ライブラリを探す必要があります。

JSON を使用したオブジェクトの上書き

既存のオブジェクトに JSON データをデシリアライズすることもでき、その場合は既存のデータが上書きされます。

JsonUtility.FromJsonOverwrite(json, myObject);

JSON データにフィールドの値が含まれていない場合、シリアライザーはそのフィールドの値を変更しません。この方法では、以前に作成したオブジェクトを再利用することで、割り当てを最小限に抑えることができます。また、フィールドの一部のサブセットしか含まれていない JSON で意図的に上書きすることで、オブジェクトに “パッチ” 処理を行うこともできます。

注意: JSON Serializer API は、MonoBehaviourScriptableObject のサブクラスのほか、簡易な構造体やクラスもサポートしています。ただし、JSON を MonoBehaviourScriptableObject のサブクラスにデシリアライズする場合は、FromJsonOverwrite メソッドを使用する必要があります。FromJson を使おうとすると、この動作はサポートされていないため、例外がスローされます。

サポートする型

JSON Serializer API は、MonoBehaviour サブクラス、ScriptableObject サブクラス、Serializable 属性を持つ簡易なクラスや構造体をサポートしています。オブジェクトを標準の Unity シリアライザーに渡して処理する際には、Inspector での処理と同じルールと制限が適用されます。Unity はフィールドのみをシリアライズします。また、Dictionary<> のような型はサポートされません。

Unity は、プリミティブ型や配列など、他の型を直接 API に渡すことをサポートしていません。それらを変換する必要がある場合は、クラス または 構造体 のような形でラップしてください。

エディターのみでは、並列 API である EditorJsonUtility によって、UnityEngine.Object から派生する任意のオブジェクトを、JSONにシリアライズしたり、その逆を行うことができます。これにより、オブジェクトの YAML 形式と同じデータを含む JSON が生成されます。

パフォーマンス

ベンチマークテストによると、JsonUtility は、このクラスが提供する機能があるケースでは少ないにもかかわらず、一般的な .NET JSON ソリューションよりも大幅に高速です。

ガベージコレクション (GC) のためのメモリ使用量は最小限に抑えられています。

  • ToJson は、返された文字列に対してのみ GC メモリを割り当てます。
  • FromJson は返されたオブジェクトだけでなく、必要なサブオブジェクトに対しても GC メモリを割り当てます (例えば、配列を含むオブジェクトをデシリアライズする場合、Unity は配列に対して GC メモリを割り当てます)。
  • FromJsonOverwrite は、書き込まれたフィールド (たとえば、文字列や配列) に必要量だけ GC メモリを割り当てます。つまり、JSON で上書きされるフィールドがすべて値型である場合、Unity は GC メモリをまったく割り当てません。

JsonUtility API は、バックグラウンドのスレッドから使用することができます。ただし、他のマルチスレッドコードと同様に、あるスレッドでオブジェクトをシリアライズまたはデシリアライズしている間に、別のスレッドでオブジェクトにアクセスしたり変更したりしないように注意してください。

ToJson() の出力の制御

ToJson メソッドは、JSON 出力の整形表示 (pretty-print) をサポートしています。デフォルトではオフになっていますが、true を 2 番目のパラメーターとして渡すことでオンにすることができます。

NonSerialized 属性を使用すると、出力からフィールドを除くことができます。

未知の型で FromJson() を使用

オブジェクトの型が事前にわからない場合は、JSON を “共通” のフィールドを含むクラスや構造体にデシリアライズし、そのフィールドの値を使って実際に必要な型を調べます。その後、2 回目のデシリアライズでその型に変換します。

スクリプトのシリアル化に関連するエラー
スクリプトのコンパイル