serialisasi internal
Kesalahan serialisasi Script

serialisasi kustom

Serialisasi adalah proses otomatis dari mengubah struktur data atau objek menyatakan ke dalam format yang dapat disimpan Unity dan rekonstruksi nanti. (Lihat dokumentasi tentang Serialisasi Script untuk informasi lebih lanjut tentang serialisasi Unity.)

Kadang-kadang Anda mungkin ingin serialisasi sesuatu yang serializer Unity tidak mendukung. Dalam banyak kasus pendekatan terbaik adalah menggunakan callback serialisasi. (Lihat Referensi API Scripting Unity: ISerializationCallbackReceiver untuk informasi lebih lanjut tentang serialisasi kustom menggunakan callback serlialisasi.)

Serialisasi callback memungkinkan Anda untuk diberitahukan sebelum serializer membaca data dari bidang Anda dan setelah selesai menulis kepada mereka. Anda dapat menggunakan callback serialisasi untuk memberikan data hard-to-serialize yang berbeda pada runtime ke representasinya ketika Anda benar-benar serialisasi.

Untuk melakukan ini, mengubah data Anda ke dalam sesuatu Unity memahami tepat sebelum Unity ingin serialisasi itu. Kemudian, tepat setelah Unity telah menulis data ke bidang Anda, Anda dapat mengubah formulir serialisasi kembali ke formulir yang ingin Anda miliki data Anda di runtime

Contoh: Anda ingin memiliki struktur data pohon. Jika Anda membiarkan Unity langsung serialisasi struktur data, batasan "tidak mendukung untuk null" akan menyebabkan aliran data Anda menjadi sangat besar, menyebabkan degradasi kinerja dalam banyak sistem. Ini ditunjukkan dalam Contoh 1, di bawah ini.

Example 1: Unity's direct serlialization, menyebabkan masalah kinerja


using UnityEngine;
using System.Collections.Generic;
using System;

public class VerySlowBehaviourDoNotDoThis : MonoBehaviour {
    [Serializable]
    public class Node {
        public string interestingValue = "value";
        //The field below is what makes the serialization data become huge because
        //it introduces a 'class cycle'.
        public List<Node> children = new List<Node>();
    }
    //this gets serialized
    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 ();
    }
}

Alih-alih, Anda memberitahu Unity tidak untuk men serialisasi pohon secara langsung, dan Anda membuat bidang yang terpisah untuk menyimpan pohon dalam format serial, cocok untuk serializer Unity. Ini ditunjukkan dalam Contoh 2, di bawah ini.

Example 2: Hindari serlialisasi langsung Unity dan menghindari masalah kinerja


using System.Collections.Generic;
using System;

public class BehaviourWithTree : MonoBehaviour, ISerializationCallbackReceiver {
    // Node class that is used at runtime.
    // This is internal to the BehaviourWithTree class and is not serialized.
    public class Node {
        public string interestingValue = "value";
        public List<Node> children = new List<Node>();
    }
    // Node class that we will use for serialization.
    [Serializable]
    public struct SerializableNode {
        public string interestingValue;
        public int childCount;
        public int indexOfFirstChild;
    }
    // The root node used for runtime tree representation. Not serialized.
    Node root = new Node();
    // This is the field we give Unity to serialize.
    public List<SerializableNode> serializedNodes;
    public void OnBeforeSerialize() {
        // Unity is about to read the serializedNodes field's contents.
        // The correct data must now be written into that field "just in time".
        if (serializedNodes == null) serializedNodes = new List<SerializableNode>();
        if (root == null) root = new Node ();
        serializedNodes.Clear();
        AddNodeToSerializedNodes(root);
        // Now Unity is free to serialize this field, and we should get back the expected 
        // data when it is deserialized later.
    }
    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 has just written new data into the serializedNodes field.
        //let's populate our actual runtime data with those new values.
        if (serializedNodes.Count > 0) {
            ReadNodeFromSerializedNodes (0, out root);
        } else
        root = new Node ();
    }
    int ReadNodeFromSerializedNodes(int index, out Node node) {
        var serializedNode = serializedNodes [index];
        // Transfer the deserialized data into the internal Node class
        Node newNode = new Node() {
            interestingValue = serializedNode.interestingValue,
            children = new List<Node> ()
        }
        ;
        // The tree needs to be read in depth-first, since that's how we wrote it out.
        for (int i = 0; i != serializedNode.childCount; i++) {
            Node childNode;
            index = ReadNodeFromSerializedNodes (++index, out childNode);
            newNode.children.Add (childNode);
        }
        node = newNode;
        return index;
    }
    // This OnGUI draws out the node tree in the Game View, with buttons to add new nodes as children.
    void OnGUI() {
        if (root != null) {
            Display (root);
        }
    }
    void Display(Node node) {
        GUILayout.Label ("Value: ");
        // Allow modification of the node's "interesting 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 ();
    }
}




• 2017–05–15 Sitemap

serialisasi internal
Kesalahan serialisasi Script