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.Thử thách
Trung bìnhXoay đầu mỗi tháp để hướng về mục tiêu.
- Trong
Tower, thêm[SerializeField] private Transform head;và[SerializeField] private float turnSpeed = 270f;. - Khi có mục tiêu, chỉ xoay
headquanh trục y để hướng về mục tiêu, tối đaturnSpeed * Time.deltaTimeđộ, bằngQuaternion.RotateTowards. - 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