Menu
CoddyTech

Thành phần trừu tượng

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 3 trên 64.

Một số lớp cơ sở mô tả một loại đối tượng không bao giờ tồn tại độc lập. Mọi vũ khí đều khai hỏa, nhưng một vũ khí không phải súng lục hay súng săn thì không có cách nào để khai hỏa. Đánh dấu lớp như vậy là abstract, rồi khai báo mỗi bước mà lớp con phải viết thành một phương thức trừu tượng, không có phần thân:

public abstract class Weapon : MonoBehaviour
{
    public int shots;

    public void Pull()
    {
        shots++;
        Fire();
    }

    protected abstract void Fire();
}
public class Shotgun : Weapon
{
    public GameObject pelletPrefab;

    protected override void Fire()
    {
        for (int i = -1; i <= 1; i++)
        {
            Instantiate(pelletPrefab, transform.position + transform.right * i * 0.3f, transform.rotation);
        }
    }
}

Lớp con không viết Fire sẽ không biên dịch được: CS0534, 'Pistol' does not implement inherited abstract member 'Weapon.Fire()'. Unity cũng không cho phép gắn một script trừu tượng vào đối tượng. Kéo Weapon vào đối tượng, bạn sẽ thấy thông báo Can't add script behaviour 'Weapon'. The script class can't be abstract!, vì Unity không thể tạo một Weapon không có Fire.

Các script khác vẫn hoạt động với kiểu cơ sở. GetComponent<Weapon>() trả về lớp con đang gắn trên đối tượng, còn Pull() chạy Fire của lớp con đó:

// Player.cs
private Weapon weapon;

void Start()
{
    weapon = GetComponent<Weapon>();
}

void Update()
{
    if (Mouse.current.leftButton.wasPressedThisFrame)
    {
        weapon.Pull();
    }
}

Thay thành phần Shotgun bằng Pistol, script Player vẫn giữ nguyên.

challenge icon

Thử thách

Dễ

Biến Monster thành lớp trừu tượng để tháp đánh mọi loại quái vật.

  1. Trong Monster, viết public abstract class Monster và protected abstract void React();, không có phần thân.
  2. Giờ trình biên dịch sẽ chỉ ra lỗi ở Imp: thêm protected override void React() để cộng Vector3.forward * 2f vào vị trí của nó.
  3. Trong Tower, bên trong vòng lặp, gọi Zap() trên target.GetComponent<Monster>().

Nhấn Chơi rồi nhấn phím cách: slime sẽ co nhỏ, imp sẽ nhảy lùi lại. Sau đó nhấn Kiểm tra.

Tự làm thử

using UnityEngine;

// Đặc điểm chung của mọi quái vật.
public class Monster : MonoBehaviour
{
    public int hp = 3;

    public void Zap()
    {
        hp--;
        if (hp <= 0)
        {
            Destroy(gameObject);
        }
        else
        {
            React();
        }
    }

    // Cách loại quái vật này phản ứng sau khi trúng đòn điện mà vẫn sống.
    protected virtual void React()
    {
    }
}

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

Tự luyện tập: Playground Unity