Menu
CoddyTech

Lớp có thể tuần tự hóa

Thuộc phần Kiến trúc trò chơi trong Unity trong hành trình Unity của Coddy. Bài học 18 trên 64.

Một script có nhiều thiết lập sẽ tạo ra một danh sách phẳng dài trong Inspector. Bạn có thể dùng một lớp C# thông thường để nhóm chúng lại: đánh dấu lớp bằng [System.Serializable], rồi một trường thuộc lớp đó sẽ hiển thị thành một mục có thể mở rộng mang tên trường, bên trong là các trường của lớp. Một lớp có thể dùng cho nhiều trường và nhiều script:

[System.Serializable]
public class Stats
{
    public float speed = 2f;
    public int damage = 10;
}

public class Enemy : MonoBehaviour
{
    public Stats normal;
    public Stats enraged;
    private Stats current;

    void Start()
    {
        current = normal;
    }

    void Update()
    {
        transform.Translate(0f, 0f, current.speed * Time.deltaTime);
    }

    public void Enrage()
    {
        current = enraged;
    }
}

Inspector hiển thị hai mục có thể mở rộng, Normal và Enraged, mỗi mục có Speed và Damage. Mỗi Enemy có hai đối tượng Stats riêng, được điền trong Inspector riêng, và code đọc chúng như normal.speed. Unity tạo các đối tượng này khi tải script, vì vậy normal không bao giờ là null ngay cả khi không có = new Stats(), và các giá trị khởi tạo của trường (2 và 10) là giá trị ban đầu của một Enemy mới. Một struct cũng hoạt động tương tự với thuộc tính này, [System.Serializable] public struct Range { public float min; public float max; }, và giống như Vector3, nó được sao chép khi gán.

Cần có thuộc tính này vì Unity chỉ lưu các kiểu dữ liệu mà nó được yêu cầu lưu. Nếu thiếu thuộc tính này, lớp sẽ không hiển thị trong Inspector: không có mục nào để mở rộng, các giá trị đặt ở đó sẽ không được lưu, và Unity cũng không tạo đối tượng, nên normal.speed gây ra NullReferenceException. Bên trong lớp, các quy tắc Inspector thông thường vẫn áp dụng: dùng trường public hoặc trường private có [SerializeField], không dùng thuộc tính hay trường static.

challenge icon

Thử thách

Dễ

Nhóm các thiết lập của từng tia sáng vào một struct.

  1. Phía trên Flashlight, khai báo public struct Beam với các trường công khai Color color, float range và float angle. Đánh dấu struct bằng [System.Serializable] để Inspector hiển thị nó.
  2. Thay sáu trường riêng lẻ bằng public Beam wide; và public Beam focused;.
  3. Trong Apply(), đặt ba giá trị của đèn từ focusedOn ? focused : wide.

Nhấn Chơi rồi nhấn Space: tia sáng chiếu tới tinh thể. Sau đó nhấn Kiểm tra.

Tự làm thử

using UnityEngine;
using UnityEngine.InputSystem;

public class Flashlight : MonoBehaviour
{
    public Color wideColor = Color.white;
    public float wideRange = 5f;
    public float wideAngle = 60f;
    public Color focusedColor = Color.white;
    public float focusedRange = 10f;
    public float focusedAngle = 30f;
    private bool focusedOn;
    private Light lamp;

    void Start()
    {
        lamp = GetComponent<Light>();
        Apply();
    }

    void Update()
    {
        if (Keyboard.current.spaceKey.wasPressedThisFrame)
        {
            focusedOn = !focusedOn;
            Apply();
        }
    }

    void Apply()
    {
        lamp.color = focusedOn ? focusedColor : wideColor;
        lamp.range = focusedOn ? focusedRange : wideRange;
        lamp.spotAngle = focusedOn ? focusedAngle : wideAngle;
    }
}

Tất cả bài học trong Kiến trúc trò chơi trong Unity

Tự luyện tập: Playground Unity