Menu
CoddyTech

IDamageable

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

Giao diện là danh sách các phương thức mà một lớp cam kết sẽ có, nhưng không có code bên trong. Những lớp không có điểm chung nào khác vẫn có thể đưa ra cùng một cam kết. Trong C# cơ bản:

interface IGreeter
{
    string Greet();
}

class Robot : IGreeter
{
    public string Greet() { return "Beep"; }
}

class Cat : IGreeter
{
    public string Greet() { return "Meow"; }
}

Biến có kiểu IGreeter có thể chứa Robot hoặc Cat, và greeter.Greet() sẽ chạy phương thức tương ứng với đối tượng mà biến đang chứa. Một lớp liệt kê IGreeter nhưng không có phương thức công khai Greet() sẽ không biên dịch được.

Trong trò chơi, nhiều thứ có thể bị gây sát thương, nhưng ngoài ra chúng hầu như không có điểm chung: người chơi có điểm máu, còn thùng gỗ vỡ ngay khi bị đánh trúng lần đầu. Một lớp cơ sở chung sẽ buộc chúng vào cùng một họ. Giao diện gọi tên điểm chung duy nhất đó, còn mỗi script triển khai theo cách riêng:

public interface IDamageable
{
    void TakeDamage(int amount);
}
public class PlayerHealth : MonoBehaviour, IDamageable
{
    public int hp = 10;

    public void TakeDamage(int amount)
    {
        hp -= amount;
        Debug.Log("Ouch! hp: " + hp);
    }
}
public class Crate : MonoBehaviour, IDamageable
{
    public void TakeDamage(int amount)
    {
        Destroy(gameObject);
    }
}

Script vẫn chỉ có một lớp cơ sở là MonoBehaviour, rồi liệt kê các giao diện sau lớp đó. Giao diện nằm trong tệp riêng có tên IDamageable.cs và không kế thừa từ MonoBehaviour: nó không phải thành phần và không bao giờ được gắn riêng lên một đối tượng. Lớp liệt kê giao diện này phải có phương thức công khai TakeDamage(int), nếu không sẽ không biên dịch được.

Thứ gây sát thương sẽ yêu cầu giao diện, chứ không yêu cầu một lớp cụ thể:

// Fireball.cs
void OnCollisionEnter(Collision collision)
{
    IDamageable target = collision.gameObject.GetComponent<IDamageable>();
    if (target != null)
    {
        target.TakeDamage(3);
    }
    Destroy(gameObject);
}

Quả cầu lửa gây sát thương cho người chơi và phá hủy thùng gỗ bằng cùng một đoạn code. Sau này, bạn có thể thêm một loại mục tiêu mới mà không cần sửa đoạn code này. Unity không hiển thị trường có kiểu giao diện trong Inspector, nên các script giữ một GameObject hoặc một thành phần rồi yêu cầu nó trả về giao diện, giống như cách quả cầu lửa làm.

challenge icon

Thử thách

Dễ

Cho người tuyết, cái chuông và bù nhìn triển khai IDamageable để búa có thể đánh trúng chúng.

  1. Snowman: TakeDamage thu nhỏ nó theo mức 0.25f * amount trên mỗi trục; nếu kích thước còn 0.5 trở xuống thì hủy nó.
  2. Bell: ghi Dong một lần cho mỗi điểm và cộng amount vào rings.
  3. Scarecrow: chỉ đòn đánh đầu tiên mới chạy transform.Rotate(0f, 0f, 90f);.
  4. Trong Slam, gọi TakeDamage(power) trên IDamageable của từng collider, nếu có.

Nhấn Chơi rồi vung búa đánh từng mục tiêu. Sau đó nhấn Kiểm tra.

Tự làm thử

using UnityEngine;

public class Snowman : MonoBehaviour
{
}

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

Tự luyện tập: Playground Unity