Odin Inspector 系列教程 --- 初識Odin序列化

前言,在Unity開發(fā)中,一些掛在物體上的腳本公開的成員變量,可通過inspector面板更改對應(yīng)的值,但并不是所有公開成員的值,都可以通過inspector面板進(jìn)行填寫,而且有些數(shù)值即使填寫,也保存不了(無法序列化),例如:Dictionary<Tkey,TValue>。但是Odin為我們提供了一套解決這種情況的序列化方案。

如下圖所示,keyValuePairs_0成員和keyValuePairs_1成員都無法進(jìn)行有效的序列化,雖然keyValuePairs_1通過特性ShowInInspector強(qiáng)制顯示出對應(yīng)的Dictionary,也可以填寫,但是在運(yùn)行時,填寫的數(shù)據(jù)會丟失。

public class ExampleUnitySerializedScript : MonoBehaviour
{
    public Dictionary<int, string> keyValuePairs_0 = new Dictionary<int, string>();

    [ShowInInspector]
    public Dictionary<int, string> keyValuePairs_1 = new Dictionary<int, string>();
}

使用Odin序列化

使用比較簡單,默認(rèn)情況下我們繼承的是 MonoBehaviour,現(xiàn)在我們只需要用SerializedMonoBehaviour代替MonoBehaviour即可,即開即用,非常簡單。

public class ExampleUnitySerializedScript : SerializedMonoBehaviour
{
    public Dictionary<int, string> keyValuePairs_0 = new Dictionary<int, string>();

    [ShowInInspector]
    public Dictionary<int, string> keyValuePairs_1 = new Dictionary<int, string>();
}

對應(yīng)SerializedMonoBehaviour這類Odin序列化類,總共有以下7種,足以滿足日常開發(fā)中的絕大多數(shù)需求

  • SerializedMonoBehaviour
  • SerializedBehaviour
  • SerializedComponent
  • SerializedNetworkBehaviour
  • SerializedScriptableObject
  • SerializedStateMachineBehaviour
  • SerializedUnityObject

這時有同學(xué)會問,Odin序列化是不是強(qiáng)制替換了原有的Unity序列化?有什么需要注意的地方呢?

第一個問題:Odin序列化默認(rèn)情況是不會替換Unity原有序列化的,Odin序列化僅僅是基于Unity序列化的擴(kuò)展,對成員進(jìn)行序列化時,如果Unity支持,就使用Unity序列化,如果不支持,轉(zhuǎn)由Odin序列化接手。

第二個問題:注意事項(xiàng)是有的,就像剛剛的回答,默認(rèn)的情況下Odin不會替換Unity原有支持的序列化情況,但是我們可以強(qiáng)制使用Odin序列化,或者強(qiáng)制讓Unity序列化和Odin序列化并存,當(dāng)然這種并存也會出現(xiàn)2份數(shù)據(jù),所以不建議這么做。如果對這段解答不是很理解,請看下面的示例

示例到代碼

using Sirenix.OdinInspector;
using Sirenix.Serialization;
using System;
using System.Collections.Generic;
using UnityEngine;


public class ExampleOdinSerializedScript : SerializedMonoBehaviour
{
    // 使用Odin序列化,而非Unity序列化
    public Dictionary<int, string> firstDictionary= new Dictionary<int, string>();

    // MyClassByUnity 因?yàn)闃?biāo)記為 Serializable ,所以使用Unity 自帶的序列化,而非Odin 序列化
    public MyClassByUnity myUnityReference = new MyClassByUnity();

    //強(qiáng)制使用 Odin 序列化,而不使用Unity的序列化
    [NonSerialized, OdinSerialize]
    public MyClassByOdin myOdinReference = new MyClassByOdin();

    private void Start()
    {
        Debug.Log(firstDictionary.Count);
        Debug.Log(myUnityReference.secondDictionary_Unity.Count);
        Debug.Log(myOdinReference.secondDictionary_Odin.Count);
    }
    
}

[Serializable]
public class MyClassByUnity
{
    // 雖然標(biāo)記為 OdinSerialize 特性, 但是依然不會被序列化
    [OdinSerialize]
    public Dictionary<int, string> secondDictionary_Unity = new Dictionary<int, string>();
}

[Serializable]
public class MyClassByOdin
{
    [OdinSerialize]
    [NonSerialized]
    public Dictionary<int, string> secondDictionary_Odin= new Dictionary<int, string>();
}

成員變量firstDictionary是Unity不支持的Dictionary類型,所以默認(rèn)使用Oidn 序列化,如果強(qiáng)行標(biāo)記Serializable特性會出現(xiàn)如下報錯

成員變量MyUnityReference是MyClassByUnity類型,在MyClassByUnity類中對應(yīng)的成員SecondDictionary_Unity標(biāo)記特性OdinSerialize,按常理secondDictionary_Unity字段會使用Odin序列化,但是MyClassByUnity類標(biāo)記了Serializable特性,所以MyClassByUnity會按照Unity序列化的方式,又因?yàn)镸yClassByUnity為Unity序列化不支持的類,所以直接跳過。類似一個for循環(huán)中,在索引0處執(zhí)行break,后面的數(shù)據(jù)不會遍歷一樣(此處感覺略微啰嗦)。

為了避免上面的情況發(fā)生,我們使用[NonSerialized, OdinSerialize]兩個特性,這是告訴編輯器,拒絕使用Unity原有的序列化,而是強(qiáng)制使用Odin自帶的序列化系統(tǒng),這樣,上面的問題就可迎刃而解。

Odin是一個強(qiáng)大的系統(tǒng),在后面的章節(jié)中筆者會更詳細(xì)的介紹Odin的序列化系統(tǒng),如果你感覺Odin不錯,就把他推薦給你的同伴吧


更多教程內(nèi)容詳見:革命性Unity 編輯器擴(kuò)展工具 --- Odin Inspector 系列教程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。