Tuần tra và truy đuổi
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 54 trên 71.
Một lính canh đang tuần tra sẽ đi theo lộ trình cho đến khi nhìn thấy người chơi, đuổi theo rồi quay lại lộ trình khi người chơi đi khỏi. Cả hai hành vi đều điều hướng theo cùng một cách, hướng đến một điểm, nên một phương thức có thể xử lý việc di chuyển cho cả hai. Lính canh này đi qua lại giữa hai chốt và đuổi theo người chơi khi người chơi ở trong phạm vi chaseRange:
[SerializeField] private Transform pointA;
[SerializeField] private Transform pointB;
[SerializeField] private Transform player;
[SerializeField] private float speed = 2f;
[SerializeField] private float chaseRange = 5f;
private Rigidbody rb;
private Transform goal;
void Start()
{
rb = GetComponent<Rigidbody>();
goal = pointA;
}
void FixedUpdate()
{
if (Flat(player.position - rb.position).magnitude < chaseRange)
{
WalkTo(player.position);
return;
}
if (Flat(goal.position - rb.position).magnitude < 0.2f)
{
goal = goal == pointA ? pointB : pointA;
}
WalkTo(goal.position);
}
void WalkTo(Vector3 target)
{
Vector3 dir = Flat(target - rb.position).normalized;
rb.linearVelocity = new Vector3(dir.x * speed, rb.linearVelocity.y, dir.z * speed);
}
Vector3 Flat(Vector3 v)
{
return new Vector3(v.x, 0f, v.z);
}Phần kiểm tra đuổi theo diễn ra trước, và return bỏ qua phần tuần tra, nên lính canh luôn ưu tiên đuổi theo khi người chơi ở gần. goal là một trường, vì vậy lính canh vẫn ghi nhớ điểm đến trong lúc đuổi theo: khi người chơi đi khỏi, nó tiếp tục đi đến chốt mà nó đang hướng tới.
Phần kiểm tra đã đến nơi đo khoảng cách trên mặt đất. Các chốt là điểm đánh dấu trên sàn, còn tâm của lính canh cao hơn chúng 1 đơn vị, nên khoảng cách tính cả chiều cao sẽ không bao giờ nhỏ hơn 1 và lính canh sẽ không quay đầu. Phần kiểm tra yêu cầu khoảng cách nhỏ hơn 0.2, chứ không phải đúng bằng 0: với tốc độ 2 đơn vị mỗi giây, lính canh di chuyển 0.04 đơn vị mỗi bước và hầu như không bao giờ dừng chính xác tại chốt.
Thử thách
Trung bìnhĐiều khiển robot tuần tra các điểm tuần tra và đuổi theo người chơi khi họ đến gần.
- Viết
WalkTo(Vector3 target), đặtrb.linearVelocityhướng về mục tiêu trên mặt đất với tốc độspeed, đồng thời giữ nguyên vận tốc theo trục y. - Trong
FixedUpdate(), khi người chơi ở gần hơnchaseRange, gọiWalkTo(player.position)rồireturn. - Nếu không, khi cách
waypoints[next]dưới 0.2, đặtnext = (next + 1) % waypoints.Length;, rồi di chuyển đếnwaypoints[next].
Nhấn Chơi rồi băng qua đường đi của robot. Sau đó nhấn Kiểm tra.
Tự làm thử
using UnityEngine;
public class Robot : MonoBehaviour
{
[SerializeField] private Transform[] waypoints;
[SerializeField] private Transform player;
[SerializeField] private float speed = 4f;
[SerializeField] private float chaseRange = 4f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
// Đuổi theo người chơi khi họ ở gần, nếu không thì đi theo tuyến tuần tra
}
}
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