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.
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.
Snowman:TakeDamagethu nhỏ nó theo mức0.25f * amounttrên mỗi trục; nếu kích thước còn 0.5 trở xuống thì hủy nó.Bell: ghiDongmột lần cho mỗi điểm và cộngamountvàorings.Scarecrow: chỉ đòn đánh đầu tiên mới chạytransform.Rotate(0f, 0f, 90f);.- Trong
Slam, gọiTakeDamage(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
1Thành phần, không phải hệ thống phân cấp
Thành phần nhỏTập lệnh kẻ địch cơ sởThành phần trừu tượngCác thành phần phối hợp với nhauÔn tập: tháp pháo mô-đunÔn tập: pháo nòng đôi4Dữ liệu tuần tự hóa
Lớp có thể tuần tự hóaDanh sách trong InspectorKiểu liệt kê trong InspectorÔn tập: Bảng vật phẩm rơiÔn tập: Quay vật phẩm2Giao diện trong Unity
IDamageableGiao diện và TryGetComponentGetComponentsÔn tập: phím tương tácÔn tập: đối tượng gần nhất trong tầm với5ScriptableObjects
Tài sản dữ liệuChỉ số vũ khíCài đặt dùng chungLưu gióSóng dưới dạng dữ liệuÔn tập: Cơ sở dữ liệu vật phẩmÔn tập: Mua hàng từ cửa hàng8Code có thể tái sử dụng
Phương thức mở rộngSingleton tổng quátCác hàm hỗ trợ tổng quátÔn tập: FindNearest3Sự kiện
Sự kiện C# trong UnityĐăng ký trong OnEnableCác trường UnityEventSự kiện điều khiển UIÔn tập: Cửa sổ bật lên thành tíchÔn tập: Bộ hẹn giờ cửa sổ bật lên6Lưu dữ liệu bằng JSON
JsonUtilityLưu trò chơiTải dữ liệu và giá trị mặc địnhÔn tập: các ô lưuChọn và xóa một ô lưu9Tái sử dụng đối tượng bằng pool
Vì sao cần pool đối tượngPool dùng hàng đợiObjectPool của UnityÔn tập: pool đạnTự luyện tập: Playground Unity