Menu
CoddyTech

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.

challenge icon

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.

  1. Viết WalkTo(Vector3 target), đặt rb.linearVelocity hướ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.
  2. Trong FixedUpdate(), khi người chơi ở gần hơn chaseRange, gọi WalkTo(player.position) rồi return.
  3. Nếu không, khi cách waypoints[next] dưới 0.2, đặt next = (next + 1) % waypoints.Length;, rồi di chuyển đến waypoints[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

Tự luyện tập: Playground Unity