Đuổi theo trong tầm
Thuộc phần Vật lý và lối chơi trong hành trình Unity của Coddy. Bài học 53 trên 71.
Hầu hết kẻ địch sẽ để bạn yên cho đến khi bạn đến gần. Đo khoảng cách đến người chơi ở mỗi bước vật lý và chỉ đuổi theo trong một phạm vi nhất định. Con slime này đuổi theo khi bạn ở trong sightRange và đứng yên khi bạn ở ngoài phạm vi đó:
void FixedUpdate()
{
Vector3 toPlayer = player.position - rb.position;
toPlayer.y = 0f;
if (toPlayer.magnitude < sightRange)
{
Vector3 dir = toPlayer.normalized;
rb.linearVelocity = new Vector3(dir.x * speed, rb.linearVelocity.y, dir.z * speed);
}
else
{
rb.linearVelocity = new Vector3(0f, rb.linearVelocity.y, 0f);
}
}Phần else rất quan trọng: Rigidbody giữ nguyên vận tốc cho đến khi có thứ gì đó thay đổi nó. Nếu không có phần này, slime mất dấu bạn sẽ tiếp tục trượt cho đến khi ma sát khiến nó dừng lại, còn trên băng thì nó sẽ không bao giờ dừng. Vì y được đặt thành 0 trước, toPlayer.magnitude là khoảng cách trên mặt đất, nên người chơi đứng trên một chiếc thùng bên cạnh slime vẫn được tính là đang ở cạnh nó.
Một phạm vi có điểm yếu. Người chơi đứng ở rìa phạm vi sẽ liên tục ra vào, khiến slime bắt đầu rồi dừng lại hết lần này đến lần khác. Kẻ địch tránh tình trạng này bằng hai phạm vi: chúng phát hiện người chơi khi người đó ở trong phạm vi ngắn và chỉ bỏ cuộc khi người đó ở ngoài phạm vi dài hơn. Một bool ghi nhớ kẻ địch có đang đuổi theo hay không. Khi ở giữa hai phạm vi, trạng thái này không thay đổi, nên kẻ địch tiếp tục việc đang làm.
Thử thách
Trung bìnhKhi người chơi đến gần, hãy để sói chú ý; khi người chơi ở xa, hãy để sói bỏ cuộc.
- Trong
FixedUpdate(), tính khoảng cách theo mặt phẳng đến người chơi: nếu nhỏ hơnnoticeRange, đặt trườngbool chasingthànhtrue; nếu lớn hơngiveUpRange, đặt thànhfalse. - Khi
chasinglàtrue, đặtrb.linearVelocityhướng về phía người chơi với tốc độspeed, đồng thời giữ nguyên giá trị y. - Nếu không, đặt
rb.linearVelocity = new Vector3(0f, rb.linearVelocity.y, 0f);.
Nhấn Chơi, đi đến gần con sói rồi chạy ra xa. Sau đó nhấn Kiểm tra.
Tự làm thử
using UnityEngine;
public class Wolf : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private float speed = 3f;
[SerializeField] private float noticeRange = 4f;
[SerializeField] private float giveUpRange = 8f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
// Phát hiện người chơi, ngừng đuổi theo nếu họ đi quá xa, rồi đuổi theo hoặc đứng yên
}
}
Tất cả bài học trong Vật lý và lối chơi
1Rigidbody
Trọng lực và khối lượngĐẩy bằng AddForceNhảy bằng xung lựcFixedUpdate cho vật lýVận tốcVật thể động họcÔn tập: Bệ phóng4Coroutine
InvokeInvokeRepeating, CancelInvokeCoroutine đầu tiên của bạnVòng lặp trong CoroutineDừng CoroutineÔn tập: đếm ngược10Dự án: Thoát khỏi đấu trường
Đấu trườngThợ săn2Va chạm
OnCollisionEnterMình đã va chạm với gì?Vỡ khi va chạmĐứng trên mặt đấtĐộ nảy và ma sátHình dạng colliderÔn tập: Tường có thể phá vỡ5Dự án: Cuộc đua thu thập xu
Quả bóng lănThu thập xu3Vùng kích hoạt
Collider kích hoạtOnTriggerEnterVật phẩm thu thậpThùng giữ lại phần còn lạiVùng tiêu diệtVào và thoátÔn tập: chìa khóa và cánh cửa6Raycast
Physics.RaycastRaycastHitKiểm tra mặt đất bằng tiaLayer và LayerMaskTầm nhìnOverlapSphere và SphereCastÔn tập: Dây báo động laser9Kẻ địch
Đuổi theo người chơiĐuổi theo trong tầmTuần tra và truy đuổiMáu và sát thươngĐạn trúng mục tiêuĐánh bật lùiÔn tập: Chó giữ nhàTự luyện tập: Playground Unity