Avatar
0
tvd12 Enlightened
tvd12 Enlightened
Ý nghĩa của [Serializable] attribute là gì?
Ví dụ trong đoạn code này thì [Serializable] attribute có nghĩa là gì?
using System;
using UnityEngine;

public class Player : MonoBehaviour
{
    //Create a custom struct and apply [Serializable] attribute to it
    [Serializable]
    public struct PlayerStats
    {
        public int movementSpeed;
        public int hitPoints;
        public bool hasHealthPotion;
    }

    //Make the private field of our PlayerStats struct visible in the Inspector
    //by applying [SerializeField] attribute to it
    [SerializeField]
    private PlayerStats stats;
}
  • Answer
unity serialization
Remain: 5
1 Answer
Avatar
tvd12 Enlightened
tvd12 Enlightened
A. Đầu tiên thì phải hiểu serialization là gì đã. Thì serialization là một hành động chuyển đổi dữ liệu từ dạng này sang dạng kia. Có thể là từ dạng byte[] sang Dictionary, hoặc từ Dictionary sang đối tượng và ngược lại.

B. Tiếp theo thì [Serializable] và [SerializeField] là 2 attribute nó cũng tương tự như java annotation dùng để đánh dấu lớp, trường, hàm nhằm tạo ra một ý nghĩa nào đó cho các thành phần này. Cụ thể hơn trong ví dụ thì:

  1. [Serializable] đánh dấu rằng struct PlayerStats sẽ có khả năng được chuyển đổi từ dữ liệu của Unity (có thể được lưu trong config, hoặc thành phần nào đó) sang dạng đối tượng của struct PlayerStats
  2. [SerializeField] đánh dấu rằng trường dữ liệu stats sẽ được gán dữ liệu được Unity chuyển đổi từ dữ liệu dạng raw của unity sang PlayerStats. Ngoài ra UnityEditor cũng sẽ kiểm tra xem trường dữ liệu nào được đánh dấu là [SerializeField] cũng sẽ được hiển thị trên giao diện và được set bởi Unity Editor.

Ví dụ sau đây sẽ minh họa cho việc scan các lớp có attribute là Serializable và các field có attribute là SerializeField.

class UnityEditor
{
    static void Main()
    {
        Assembly assembly = Assembly.GetExecutingAssembly();
        Type[] serializableTypes = assembly.GetTypes()
            .Where(t => t.GetCustomAttributes(typeof(Serializable), true).Length > 0)
            .ToArray();
        foreach (Type type in serializableTypes)
        {
            Console.WriteLine(type.FullName);
        }

        Type playerType = typeof(Player);
        FieldInfo[] serializedFields = playerType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
            .Where(f => f.GetCustomAttributes(typeof(SerializeField), true).Length > 0)
            .ToArray();

        foreach (FieldInfo field in serializedFields)
        {
            Console.WriteLine($"Serialized field name: {field.Name}");
        }
    }
}

Ví dụ sau đây sẽ minh họa cho set các giá trị từ editor vào Player:

class UnityEditor
{
    static void Main()
    {
        Object player = MonoBehaviourManager.Instance.GetBehaviour("player"); 
        Type playerType = typeof(Player);
        FieldInfo[] serializedFields = playerType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
            .Where(f => f.GetCustomAttributes(typeof(SerializeField), true).Length > 0)
            .ToArray();

        foreach (FieldInfo field in serializedFields)
        {
            field.SetValue(player, GetFieldValue(field.Name, field.GetType());
        }
    }
}
  • 0
  • Reply