コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】【Odin - Inspector and Serializer】シリアライズする(翻訳)

目次

メモ

はじめに

  • Odin のシリアライズシステムは、
    通常ではシリアライズされないフィールドや型をシリアライズ可能です
  • Odin では参照型の null 値や null 許容型をサポートしています

使い方

  • SerializedMonoBehaviour や SerializedScriptableObject を継承します
  • OdinSerializeAttribute を併用することで、
    private なプロパティもシリアライズ可能になります
using Sirenix.OdinInspector;
using Sirenix.Serialization;
using UnityEngine;

public class Example : SerializedMonoBehaviour
{
    // シリアライズされる記述方法
    
    public int serializedPublicField;

    [SerializeField] private int serializedPrivateField;

    public int SerializedPublicProperty { get; set; }
    
    [OdinSerialize] private int SerializedPrivateProperty { get; set; }
}

f:id:baba_s:20170724150958p:plain

  • Dictionary や null 許容型のシリアライズも可能になります
  • また、クラスのインスタンスで null 値を保持することも可能です
using Sirenix.OdinInspector;
using System.Collections.Generic;

public class Example : SerializedMonoBehaviour
{
    public Dictionary<int, string> table;

    public int? nullableIntValue;

    public class ExampleClass
    {
        public int id;
        public string name;
    }

    public ExampleClass exampleClassInstance;
}

f:id:baba_s:20170724173137p:plain

OdinSerialize と ShowInInspector の違い

  • ShowInInspector は表示されている値を保存しません(シリアライズしません)
  • OdinSerialize は表示されている値を保存します(シリアライズします)
  • HideInInspector と OdinSerialize を併用することで、
    値は保存するが、Inspector には表示しない、といったことも実装できます
using Sirenix.OdinInspector;
using Sirenix.Serialization;
using UnityEngine;

public class Example : SerializedMonoBehaviour
{
    [HideInInspector][OdinSerialize]
    private int serializeButHide;
}

f:id:baba_s:20170724173833p:plain

Unity のシリアライズにおける無限ループを避ける

  • Unity は参照型のポリモーフィズムや null 値のシリアライズをサポートしていません
  • そのため、下記のようなシリアライズの処理を記述すると
    Unity はシリアライズ時に無限ループに陥ってしまいます
using System;
using UnityEngine;

public class Example : MonoBehaviour
{
    public ExampleB example;
}

[Serializable]
public class ExampleA
{
    public ExampleB example;
}

[Serializable]
public class ExampleB : ExampleA
{
}
  • Odin は参照型のポリモーフィズムや null 値のシリアライズをサポートしています
  • そのため、前述したようなシリアライズにおける無限ループを避けることができます
using Sirenix.OdinInspector;
using Sirenix.Serialization;

public class Example : SerializedMonoBehaviour
{
    [OdinSerialize]
    public ExampleB example;
}

public class ExampleA
{
    public ExampleB example;
}

public class ExampleB : ExampleA
{
}

f:id:baba_s:20170724175422p:plain

機能と制限

  • Odin は、デフォルトで public フィールド、
    SerializeField 属性が適用された private フィールドをシリアライズします
  • そのため、通常はこれらについて深く考える必要はありません
  • Odin は Dictionary やデリゲートのシリアライズもサポートしています
  • シリアライズにはデフォルトで「バイナリ」「JSON」「ノード」の
    3 つのフォーマットを用意しています

注意

  • Odin のシリアライズシステムを使うということは、
    複雑なシステムに依存することになるため、
    Odin を Unity プロジェクトから取り除くことが難しくなります
  • また、柔軟性を高めるためにパフォーマンスを犠牲にします。
    Odin のシリアライズは高速ですが、Unity のシリアライズに対して
    ピギーバックをかけなければならないため、Unity のモノほど速くありません
  • 多くのβテストが行われ、現場でうまく使用されていますが、
    まだ微妙な問題が存在する可能性があります
  • したがって、必要のない場所では Odin のシリアライズを避けることをオススメします