最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Unity-腳本序列化

2021-01-13 14:24 作者:unity_某某師_高錦錦  | 我要投稿

序列化是將數(shù)據(jù)結(jié)構(gòu)或?qū)ο鬆顟B(tài)轉(zhuǎn)換為 Unity 可存儲(chǔ)并在以后可重構(gòu)的格式的自動(dòng)過程。Unity 的一些內(nèi)置功能會(huì)使用序列化,比如保存和加載、Inspector 窗口、實(shí)例化和預(yù)制件等功能。請(qǐng)參閱有關(guān)內(nèi)置序列化使用情況的文檔,了解所有相關(guān)的背景詳情。

數(shù)據(jù)在 Unity 項(xiàng)目中的組織方式會(huì)影響 Unity 序列化該數(shù)據(jù)的方式,并會(huì)對(duì)項(xiàng)目的性能產(chǎn)生重大影響。以下是有關(guān) Unity 中的序列化以及如何針對(duì)其進(jìn)行項(xiàng)目?jī)?yōu)化的一些準(zhǔn)則。

另請(qǐng)參閱以下相關(guān)文檔:序列化錯(cuò)誤、自定義序列化和內(nèi)置序列化。

了解熱重載

熱重載

熱重載是在 Editor 打開的狀態(tài)下創(chuàng)建或編輯腳本并立即應(yīng)用腳本行為的過程。無(wú)需重新啟動(dòng)游戲和 Editor 即可使更改生效。

更改并保存腳本時(shí),Unity 會(huì)熱重載所有當(dāng)前加載的腳本數(shù)據(jù)。它首先將所有可序列化變量存儲(chǔ)在所有加載的腳本中,并在加載腳本后恢復(fù)它們。熱重載后,所有不可序列化的數(shù)據(jù)都將丟失。

保存和加載

Unity 使用序列化技術(shù)從計(jì)算機(jī)的硬盤驅(qū)動(dòng)器加載和保存場(chǎng)景、資源和?AssetBundle。這包括保存在您自己的腳本 API 對(duì)象(如?MonoBehaviour?組件和?ScriptableObject)中的數(shù)據(jù)。

Unity Editor 中的許多功能都建立在核心序列化系統(tǒng)之上。對(duì)于序列化要特別注意的兩點(diǎn)是?Inspector 窗口和熱重載。

Inspector 窗口

在?Inspector 窗口中查看或更改游戲?qū)ο蟮慕M件字段的值時(shí),Unity 會(huì)序列化此數(shù)據(jù),然后在 Inspector 窗口中顯示數(shù)據(jù)。Inspector 窗口在顯示字段值時(shí)不與 Unity Scripting API 通信。

如果在腳本中使用屬性,則在 Inspector 窗口中查看或更改值時(shí),絕不會(huì)調(diào)用任何屬性 getter 和 setter,因?yàn)?Unity 會(huì)直接序列化 Inspector 窗口字段。這意味著:當(dāng) Inspector 窗口中的字段值表示腳本屬性時(shí),對(duì) Inspector 窗口中值的更改不會(huì)調(diào)用腳本中的任何屬性 getter 和 setter

序列化規(guī)則

Unity 中的序列化程序在實(shí)時(shí)游戲環(huán)境中運(yùn)行。這對(duì)性能有重大影響。因此,Unity 中的序列化與其他編程環(huán)境中的序列化具有不同的行為。下面列出了一些關(guān)于如何在 Unity 中使用序列化的技巧。


如何確保腳本中的字段被序列化

確保其符合以下條件:

  • 為?public,或具有?SerializeField?屬性

  • 非?static

  • 非?const

  • 非?readonly

  • 具有可序列化的?fieldtype
    (請(qǐng)參閱下面的可序列化的簡(jiǎn)單字段類型。)


可序列化的簡(jiǎn)單字段類型

  • 具有?Serializable?屬性的自定義非抽象、非泛型類
    (請(qǐng)參閱下面的如何確保自定義類可序列化。)

  • 具有?Serializable?屬性的自定義結(jié)構(gòu)

  • 對(duì)從?UnityEngine.Object?派生的對(duì)象的引用

  • 原始數(shù)據(jù)類型(int、floatdouble、bool、string?等)

  • 枚舉類型

  • 某些 Unity 內(nèi)置類型:Vector2Vector3、Vector4、Rect、Quaternion、Matrix4x4Color、Color32LayerMask、AnimationCurve、GradientRectOffset、GUIStyle

可序列化的容器字段類型

  • 可序列化的簡(jiǎn)單字段類型的數(shù)組

  • 可序列化的簡(jiǎn)單字段類型的?List<T>

注意:Unity 不支持多級(jí)類型(多維數(shù)組、交錯(cuò)數(shù)組和嵌套容器類型)的序列化。
如果要序列化這些類型,可使用兩種方法:將嵌套類型包裝在類或結(jié)構(gòu)中,或使用序列化回調(diào)?ISerializationCallbackReceiver?執(zhí)行自定義序列化。有關(guān)更多信息,請(qǐng)參閱自定義序列化的文檔。


如何確保自定義類可序列化

確保其符合以下條件:

  • 具有?Serializable?屬性

  • 非抽象

  • 非靜態(tài)

  • 非泛型(但可繼承自泛型類)

要確保自定義類或結(jié)構(gòu)的字段被序列化,請(qǐng)參閱上面的如何確保腳本中的字段被序列化。

序列化程序何時(shí)可能出現(xiàn)意外行為?

自定義類的行為類似于結(jié)構(gòu)

對(duì)于不是從?UnityEngine.Object?派生的自定義類,Unity 以內(nèi)聯(lián)方式按值對(duì)它們進(jìn)行序列化,類似于結(jié)構(gòu)的序列化方式。如果在多個(gè)不同的字段中存儲(chǔ)對(duì)自定義類的實(shí)例的引用,則在序列化時(shí)它們將成為單獨(dú)的對(duì)象。然后,當(dāng) Unity 反序列化這些字段時(shí),它們將包含具有相同數(shù)據(jù)的不同對(duì)象。

需要序列化具有引用的復(fù)雜對(duì)象圖時(shí),不要讓 Unity 自動(dòng)序列化對(duì)象。相反,應(yīng)使用?ISerializationCallbackReceiver?手動(dòng)序列化它們。這樣可以防止 Unity 從對(duì)象引用創(chuàng)建多個(gè)對(duì)象。有關(guān)更多信息,請(qǐng)參閱?ISerializationCallbackReceiver?的文檔。

這種情況僅適用于自定義類。Unity 以“內(nèi)聯(lián)”方式對(duì)自定義類進(jìn)行序列化,因?yàn)檫@些類的數(shù)據(jù)會(huì)成為使用這些類的?MonoBehaviour?或?ScriptableObject?的完整序列化數(shù)據(jù)的一部分。當(dāng)字段引用?UnityEngine.Object?派生的某個(gè)類(例如?public Camera myCamera)時(shí),Unity 會(huì)序列化對(duì)攝像機(jī)?UnityEngine.Object?的實(shí)際引用。如果腳本派生自?MonoBehaviour?或?ScriptableObject(二者均從?UnityEngine.Object?派生而來(lái)),在腳本的實(shí)例中也適用相同的序列化原則。

自定義類不支持?null

思考在反序列化一個(gè)使用以下腳本的?MonoBehaviour?時(shí)進(jìn)行了多少次分配。

出現(xiàn)一次以下分配并不奇怪:Test?對(duì)象的一次分配。另外,出現(xiàn)兩次以下分配也不奇怪:Test?對(duì)象的一次分配和?Trouble?對(duì)象的一次分配。

但是,Unity 實(shí)際上進(jìn)行超過一千次的分配。序列化程序不支持 null。如果序列化程序?qū)δ硞€(gè)對(duì)象進(jìn)行序列化,并且一個(gè)字段為 null,則 Unity 將實(shí)例化該類型的新對(duì)象,并對(duì)該對(duì)象進(jìn)行序列化。顯然,這可能導(dǎo)致無(wú)限循環(huán),因此存在七級(jí)的深度限制。達(dá)到該限制時(shí),Unity 停止序列化具有自定義類、結(jié)構(gòu)、列表或數(shù)組類型的字段。

由于 Unity 的子系統(tǒng)很多都是在序列化系統(tǒng)之上構(gòu)建的,因此?Test MonoBehaviour?的這種異常大型的序列化流會(huì)導(dǎo)致所有這些子系統(tǒng)的執(zhí)行速度低于必要速度。

不支持多態(tài)

如果具有?public Animal[] animals?并輸入一個(gè)?Dog、一個(gè)?Cat?和一個(gè)?Giraffe?的實(shí)例,則在序列化之后有三個(gè)?Animal?實(shí)例。

解決此限制的一種方法是認(rèn)識(shí)到它僅適用于內(nèi)聯(lián)序列化的自定義類。對(duì)其他?UnityEngine.Objects?的引用被序列化為實(shí)際引用,對(duì)于這些情況,多態(tài)確實(shí)有效。可創(chuàng)建一個(gè)?ScriptableObject?派生類或另一個(gè)?MonoBehaviour?派生類,并引用該類。這樣做的缺點(diǎn)是需要在某處存儲(chǔ)該?Monobehaviour?或腳本化對(duì)象,并且無(wú)法有效地對(duì)其進(jìn)行內(nèi)聯(lián)序列化。

設(shè)置這些限制的原因是序列化系統(tǒng)的核心基礎(chǔ)之一是提前知道對(duì)象的數(shù)據(jù)流布局;它取決于類的字段類型,而不是存儲(chǔ)在字段內(nèi)的具體內(nèi)容。

提示

序列化的優(yōu)化應(yīng)用

您可以組織數(shù)據(jù)來(lái)確保從 Unity 的序列化獲得最佳使用效果。

  • 組織數(shù)據(jù)的目的是讓 Unity 序列化盡可能小的數(shù)據(jù)集。這樣做的主要目的不是為了節(jié)省計(jì)算機(jī)硬盤驅(qū)動(dòng)器上的空間,而是為了確保您可以保持與項(xiàng)目以前版本的向后兼容性。如果使用大型的序列化數(shù)據(jù)集,那么在開發(fā)后期保持向后兼容性會(huì)變得更加困難。

  • 組織數(shù)據(jù)時(shí)確保絕不會(huì)讓 Unity 序列化重復(fù)的數(shù)據(jù)或緩存的數(shù)據(jù)。否則會(huì)導(dǎo)致向后兼容性出現(xiàn)嚴(yán)重問題:存在著很高的錯(cuò)誤風(fēng)險(xiǎn),因?yàn)閿?shù)據(jù)太容易失去同步。

  • 避免使用嵌套的遞歸結(jié)構(gòu)引用其他類。序列化結(jié)構(gòu)的布局總是必須相同;獨(dú)立于數(shù)據(jù),僅依賴于腳本中公開的內(nèi)容。引用其他對(duì)象的唯一方法是通過?UnityEngine.Object?派生的類。這些類是完全獨(dú)立的;它們只互相引用,沒有嵌入內(nèi)容。

使 Editor 代碼可熱重載

重新加載腳本時(shí),Unity 會(huì)在所有加載的腳本中序列化并存儲(chǔ)所有變量。重新加載腳本后,Unity 會(huì)將它們恢復(fù)為序列化前的原始值。

重新加載腳本時(shí),Unity 會(huì)恢復(fù)滿足序列化要求的所有變量(包括私有變量),即使變量沒有?SerializeField?屬性也是如此。在某些情況下,需要特意防止恢復(fù)私有變量:例如,如果您希望從腳本重新加載后引用為 null。在這種情況下,請(qǐng)使用?NonSerialized?屬性。

Unity 絕不會(huì)恢復(fù)靜態(tài)變量,因此對(duì)于重新加載腳本后需要保留的狀態(tài),不要使用靜態(tài)變量。


Unity-腳本序列化的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
雷州市| 林西县| 台北市| 东丽区| 新野县| 大荔县| 磐安县| 赤壁市| 辰溪县| 习水县| 济宁市| 聂荣县| 宜丰县| 漳平市| 将乐县| 资溪县| 宁化县| 汪清县| 康马县| 铜山县| 保山市| 中方县| 四子王旗| 光山县| 会昌县| 尖扎县| 观塘区| 华蓥市| 游戏| 务川| 定安县| 星子县| 西林县| 连城县| 寿光市| 平乐县| 专栏| 太湖县| 富阳市| 城步| 青田县|