五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

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

Unity-自定義序列化

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

序列化是將數(shù)據(jù)結構或對象狀態(tài)轉換為 Unity 可存儲并在以后可重構的格式的自動過程。(請參閱有關腳本序列化的文檔以了解關于 Unity 序列化的更多信息。)

有時可能希望序列化 Unity 的序列化程序不支持的內容。在許多情況下,最好的辦法是使用序列化回調。(請參閱 Unity 的腳本 API 參考:ISerializationCallbackReceiver,了解關于使用序列化回調進行自定義序列化的更多信息。)

序列化回調可讓您在序列化程序從字段中讀取數(shù)據(jù)之前以及在完成對字段的寫入之后收到通知。使用序列化回調可在運行時為難以序列化的數(shù)據(jù)賦予不同于實際序列化時的表示形式。

為實現(xiàn)此目的,請在 Unity 要序列化數(shù)據(jù)之前將數(shù)據(jù)轉換為 Unity 理解的表示形式。然后,在 Unity 將數(shù)據(jù)寫入字段之后,可將序列化的形式轉換回在運行時需要的數(shù)據(jù)形式。

例如:您需要一個樹數(shù)據(jù)結構。如果讓 Unity 直接序列化該數(shù)據(jù)結構,“不支持 null”限制將導致數(shù)據(jù)流變得非常大,從而在許多系統(tǒng)中引起性能下降。下面的示例 1 中顯示了這一情況。

示例 1:Unity 的直接序列化,導致性能問題

using UnityEngine;?

using System.Collections.Generic;?

using System;?

public class VerySlowBehaviourDoNotDoThis : MonoBehaviour {?

[Serializable]?

public class Node {

public string interestingValue = "value"; ?

?//下面的字段使序列化數(shù)據(jù)變得巨大

//因為它引入了"類周期"

public List<Node> children = new List<Node>();?

} ? ?

//這將經(jīng)過序列化 ? ?

public Node root = new Node(); ? ?

void OnGUI() {?

Display (root);?

} ? ?

void Display(Node node) {

GUILayout.Label ("Value: "); ? ? ? ?

node.interestingValue = GUILayout.TextField(node.interestingValue, GUILayout.Width(200)); ? ? ? ?GUILayout.BeginHorizontal (); ? ? ? ?

GUILayout.Space (20); ? ? ? ?

GUILayout.BeginVertical (); ? ? ? ?

foreach (var child in node.children) ? ? ??

?Display (child); ? ? ? ?if (GUILayout.Button ("Add child")) ? ? ? ?

node.children.Add (new Node ()); ? ? ? ?

GUILayout.EndVertical (); ? ? ? ?

GUILayout.EndHorizontal (); ? ?} }

相反,您告訴 Unity 不要直接序列化樹,并創(chuàng)建單獨的字段來以序列化的格式(適用于 Unity 序列化程序)存儲樹。下面的示例 2 中顯示了這一情況。

示例 2:避免 Unity 直接序列化,并避免性能問題

using System.Collections.Generic;

using System;

using UnityEngine;

public class BehaviourWithTree : MonoBehaviour

{

? ? // 在運行時使用的 Node 類。

? ? //此類位于 BehaviourWithTree 類的內部,不會被序列化。

? ? public class Node

? ? {

? ? ? ? public string interestingValue = "value";

? ? ? ? public List<Node> children = new List<Node>();

? ? }

? ? // 我們將用于序列化的 Node 類。

? ? [Serializable]

? ? public struct SerializableNode

? ? {

? ? ? ? public string interestingValue;

? ? ? ? public int childCount;

? ? ? ? public int indexOfFirstChild;

? ? }

? ? //用于運行時樹表示的根節(jié)點。不序列化。

? ? Node root = new Node();

? ? //這是我們提供給 Unity 進行序列化的字段。

? ? public List<SerializableNode> serializedNodes;

? ? public void OnBeforeSerialize()

? ? {

? ? ? ? //Unity 即將讀取 serializedNodes 字段的內容。

? ? ? ? // 現(xiàn)在必須"及時"將正確的數(shù)據(jù)寫入該字段。

? ? ? ? if (serializedNodes == null) serializedNodes = new List<SerializableNode>();

? ? ? ? if (root == null) root = new Node();

? ? ? ? serializedNodes.Clear();

? ? ? ? AddNodeToSerializedNodes(root);

? ? ? ? // 現(xiàn)在 Unity 可自由地序列化這個字段,我們應該在稍后反序列化時

? ? ? ? // 找回預期的數(shù)據(jù)。

? ? }

? ? void AddNodeToSerializedNodes(Node n)

? ? {

? ? ? ? var serializedNode = new SerializableNode()

? ? ? ? {

? ? ? ? ? ? interestingValue = n.interestingValue,

? ? ? ? ? ? childCount = n.children.Count,

? ? ? ? ? ? indexOfFirstChild = serializedNodes.Count + 1

? ? ? ? }

? ? ? ? ;

? ? ? ? serializedNodes.Add(serializedNode);

? ? ? ? foreach (var child in n.children)

? ? ? ? ? ? AddNodeToSerializedNodes(child);

? ? }

? ? public void OnAfterDeserialize()

? ? {

? ? ? ? //Unity 剛剛將新數(shù)據(jù)寫入 serializedNodes 字段。

? ? ? ? //讓我們用這些新值填充我們的實際運行時數(shù)據(jù)。

? ? ? ? if (serializedNodes.Count > 0)

? ? ? ? {

? ? ? ? ? ? ReadNodeFromSerializedNodes(0, out root);

? ? ? ? }

? ? ? ? else

? ? ? ? ? ? root = new Node();

? ? }

? ? int ReadNodeFromSerializedNodes(int index, out Node node)

? ? {

? ? ? ? var serializedNode = serializedNodes[index];

? ? ? ? //將反序列化的數(shù)據(jù)傳輸?shù)絻炔?Node 類

? ? ? ? Node newNode = new Node()

? ? ? ? {

? ? ? ? ? ? interestingValue = serializedNode.interestingValue,

? ? ? ? ? ? children = new List<Node>()

? ? ? ? }

? ? ? ? ;

? ? ? ? // 以深度優(yōu)先的方式讀取樹,因為這正是我們寫入樹的方式。

? ? ? ? for (int i = 0; i != serializedNode.childCount; i++)

? ? ? ? {

? ? ? ? ? ? Node childNode;

? ? ? ? ? ? index = ReadNodeFromSerializedNodes(++index, out childNode);

? ? ? ? ? ? newNode.children.Add(childNode);

? ? ? ? }

? ? ? ? node = newNode;

? ? ? ? return index;

? ? }

? ? // 此 OnGUI 在 Game 視圖中繪制出節(jié)點樹,其中包含用于添加新節(jié)點作為子項的按鈕。

? ? void OnGUI()

? ? {

? ? ? ? if (root != null)

? ? ? ? ? ? Display(root);

? ? }

? ? void Display(Node node)

? ? {

? ? ? ? GUILayout.Label("Value: ");

? ? ? ? // 允許修改節(jié)點的"有用值"。

? ? ? ? node.interestingValue = GUILayout.TextField(node.interestingValue, GUILayout.Width(200));

? ? ? ? GUILayout.BeginHorizontal();

? ? ? ? GUILayout.Space(20);

? ? ? ? GUILayout.BeginVertical();

? ? ? ? foreach (var child in node.children)

? ? ? ? ? ? Display(child);

? ? ? ? if (GUILayout.Button("Add child"))

? ? ? ? ? ? node.children.Add(new Node());

? ? ? ? GUILayout.EndVertical();

? ? ? ? GUILayout.EndHorizontal();

? ? }

}


Unity-自定義序列化的評論 (共 條)

分享到微博請遵守國家法律
抚州市| 赣州市| 南昌县| 大石桥市| 高要市| 沂南县| 黄山市| 荣昌县| 仙游县| 徐闻县| 沁阳市| 常熟市| 新建县| 理塘县| 平顶山市| 漠河县| 洪泽县| 永修县| 沙坪坝区| 保定市| 子长县| 宁乡县| 化德县| 双流县| 通化县| 西安市| 新野县| 信阳市| 宜丰县| 邢台县| 祁东县| 江安县| 鸡东县| 肥乡县| 鄂州市| 大姚县| 长垣县| 伊金霍洛旗| 富民县| 铜山县| 永靖县|