Menu
CoddyTech

Sát thương lan

Bài học 20 trên 25 trong khóa học Game Unity: thủ thành của Coddy.

Đạn pháo của Cannon phát nổ tại nơi nó rơi xuống và gây sát thương cho mọi kẻ địch gần vụ nổ, không chỉ mục tiêu. Physics.OverlapSphere(center, radius) trả về mọi collider nằm trong phạm vi radius tính từ center: kẻ địch, nhưng cả mặt đất và đường đi nữa. Mỗi collider có IDamageable đều chịu sát thương. Mục tiêu cũng nằm trong số đó vì viên đạn rơi trúng nó, nên bản thân mục tiêu không được chịu sát thương lần thứ hai. Một quả bom đẩy lùi mọi thùng hàng xung quanh:

void Explode()
{
    foreach (Collider other in Physics.OverlapSphere(transform.position, blastRadius))
    {
        if (other.TryGetComponent(out Rigidbody body))
        {
            Vector3 away = (body.position - transform.position).normalized;
            body.AddForce(away * push, ForceMode.Impulse);
        }
    }
}

Bán kính lan sát thương là dữ liệu của Cannon, nên giờ đây một viên đạn cần nhiều hơn một con số sát thương: Launch nhận cả TowerData của tháp. Bán kính lan sát thương của Arrow là 0, vì vậy các phát bắn của nó vẫn chỉ trúng riêng mục tiêu. Sát thương vẫn là một đối số riêng vì nó phụ thuộc vào cấp của tháp.

Vụ nổ cho người chơi thấy nơi viên đạn phát nổ: một khối cầu trong suốt có chiều rộng bằng vùng lan sát thương, biến mất sau một phần tư giây. Destroy(blast, 0.25f) hủy nó sau khoảng thời gian đó mà bạn không cần tự tạo bộ đếm thời gian.

challenge icon

Thử thách

Trung bình

Đạn đại bác phát nổ và gây sát thương cho mọi kẻ địch ở gần.

  1. Trong TowerData, thêm public float splashRadius; (CannonData đặt giá trị là 1.5). Launch nhận đối số thứ ba là TowerData data, do Tower truyền vào.
  2. Khi đạn đến nơi, nếu data.splashRadius > 0, mỗi IDamageable trong Physics.OverlapSphere(transform.position, data.splashRadius) chịu sát thương một lần; nếu không, chỉ mục tiêu chịu sát thương.
  3. Sau đó, hiển thị blastPrefab đã được tuần tự hóa tại đó, với tỉ lệ Vector3.one * data.splashRadius * 2f, rồi gọi Destroy(blast, 0.25f).

Nhấn Chơi: vụ nổ của Cannon gây sát thương cho các Grunt tụ lại gần nhau. Sau đó nhấn Kiểm tra.

Tự làm thử

using UnityEngine;

public class Projectile : MonoBehaviour
{
    [SerializeField] private float speed = 12f;

    private Transform target;
    private int damage;

    public void Launch(Transform target, int damage)
    {
        this.target = target;
        this.damage = damage;
    }

    void Update()
    {
        if (target == null)
        {
            Destroy(gameObject);
            return;
        }

        transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
        if (transform.position == target.position)
        {
            if (target.TryGetComponent(out IDamageable damageable))
            {
                damageable.TakeDamage(damage);
            }
            Destroy(gameObject);
        }
    }
}

Tất cả bài học trong Game Unity: thủ thành

Tự luyện tập: Playground Unity