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; }
1 Answer
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ì:
- [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
- [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