Menu
CoddyTech

Ngắm

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

Một tháp xoay để hướng về mục tiêu: không phải toàn bộ tháp, vốn đứng trên bệ, mà là đầu tháp, một đối tượng con mang nòng pháo. Khi xoay đối tượng con, mọi thứ bên dưới nó cũng xoay theo, còn đối tượng cha vẫn giữ nguyên.

Kẻ địch di chuyển thấp hơn các đầu tháp, nên hướng từ đầu tháp đến kẻ địch hơi chúc xuống, và đầu tháp hướng thẳng theo hướng đó sẽ chúi về phía trước. Đặt y của hướng thành 0 để giữ đầu tháp nằm ngang, nhờ đó nó chỉ xoay quanh trục thẳng đứng. Đèn hải đăng hướng theo một con tàu:

Vector3 toShip = ship.position - lamp.position;
toShip.y = 0f;
lamp.rotation = Quaternion.LookRotation(toShip);
Quaternion.LookRotation(direction) là phép xoay hướng về phía đó, nên đèn lập tức xoay về phía con tàu. Thay vào đó, đầu tháp cần xoay với một tốc độ nhất định: Quaternion.RotateTowards(from, to, maxDegrees) trong chương Rotation xoay tối đa maxDegrees, còn tốc độ xoay tính bằng độ mỗi giây nhân với Time.deltaTime sẽ cho biết phần xoay của mỗi khung hình.
challenge icon

Thử thách

Trung bình

Xoay đầu mỗi tháp để hướng về mục tiêu.

  1. Trong Tower, thêm [SerializeField] private Transform head; và [SerializeField] private float turnSpeed = 270f;.
  2. Khi có mục tiêu, chỉ xoay head quanh trục y để hướng về mục tiêu, tối đa turnSpeed * Time.deltaTime độ, bằng Quaternion.RotateTowards.
  3. Bắn từ nòng tháp: head.position + head.forward * 0.6f.

Nhấn Chơi: các đầu tháp xoay theo kẻ địch và bắn từ nòng tháp. Sau đó nhấn Kiểm tra.

Tự làm thử

using UnityEngine;

public class Tower : MonoBehaviour
{
    public float range = 4f;
    public int damage = 2;
    [SerializeField] private Projectile projectilePrefab;

    private Enemy target;
    private float nextShot;

    void Update()
    {
        Enemy found = FindTarget();
        if (found != null && found != target)
        {
            Debug.Log("Target: " + found.name);
        }
        target = found;
        if (target == null)
        {
            return;
        }

        if (Time.time >= nextShot)
        {
            Fire();
            nextShot = Time.time + 1f;
        }
    }

    Enemy FindTarget()
    {
        Enemy nearest = null;
        float nearestDistance = range;
        foreach (Enemy enemy in Enemy.All)
        {
            float distance = Vector3.Distance(transform.position, enemy.transform.position);
            if (distance <= nearestDistance)
            {
                nearest = enemy;
                nearestDistance = distance;
            }
        }
        return nearest;
    }

    void Fire()
    {
        Projectile shot = Instantiate(projectilePrefab, transform.position + Vector3.up, Quaternion.identity);
        shot.Launch(target.transform, damage);
    }
}

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

Tự luyện tập: Playground Unity