[Serializable] Và [SerializeField] Khác Nhau Thế Nào?
Minh Khoa
Tác giả
Không thể tải ảnh bên ngoài> Câu trả lời ngắn: [SerializeField] chọn field nào cần được Unity lưu. [Serializable] cho Unity biết custom class hoặc struct này có thể được lưu như data.
Một cái đặt trên field, một cái đặt trên type. Chúng không thay thế cho nhau.
Ví Dụ Dễ Nhất: Vũ Khí Của Nhân Vật
Ta muốn chỉnh vũ khí khởi đầu ngay trong Inspector:
using System;
using UnityEngine;
[Serializable]
public class WeaponData
{
[SerializeField] private string weaponName = "Wooden Sword";
[SerializeField] private int damage = 10;
public string Name => weaponName;
public int Damage => damage;
}
public class Player : MonoBehaviour
{
[SerializeField] private WeaponData startingWeapon = new WeaponData();
}
Trong đoạn code này:
[SerializeField] private WeaponData startingWeapon;
└─ Chọn field cần lưu
[Serializable] public class WeaponData
└─ Cho phép Unity lưu data bên trong type này
Mở Inspector của Player, chúng ta sẽ thấy Starting Weapon, bên trong có Weapon Name và Damage.
[SerializeField]: Tôi Muốn Unity Lưu Field Này
Unity tự serialize public field nếu type của nó được hỗ trợ:
public int health = 100;
Nhưng public field cũng cho code bên ngoài sửa trực tiếp:
player.health = -999;
Thường nên giữ field là private và chỉ mở nó cho Inspector:
[SerializeField] private int health = 100;
public int Health => health;
health vẫn được lưu trong Scene hoặc Prefab, nhưng class khác không thể tùy tiện sửa nó.
[SerializeField]nghĩa là “hãy lưu field này”, không phải “hãy làm type này serialize được”.
Ví dụ sau vẫn không hoạt động như mong đợi:
[SerializeField] private Dictionary<string, int> inventory;
Vì Dictionary không được Unity serializer hỗ trợ trực tiếp. Gắn thêm [SerializeField] không thể thay đổi rule đó.
[Serializable]: Custom Type Này Có Thể Chứa Data Được Lưu
int, float, string, Vector3, và nhiều type có sẵn đã được Unity biết cách xử lý.