Menu
CoddyTech

巡逻与追逐

本课属于 Coddy Unity 学习旅程的“物理与游戏玩法”单元。第 54 课,共 71 课。

巡逻中的守卫会沿着路线行走,直到发现玩家,然后追赶玩家;玩家离开后,它会回到路线。两种行为的转向方式相同,都是朝着某个点移动,所以可以用一个方法来完成两种行走行为。这个哨兵会在两个岗哨之间来回移动,并在玩家进入 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);
}

先检查是否需要追赶,return 会跳过巡逻代码,因此只要玩家靠近,追赶行为就会优先执行。goal 是一个字段,所以哨兵会在追赶期间记住目标:玩家离开后,它会继续前往原本要去的岗哨。

抵达检测会测量地面上的距离。岗哨是地面上的标记,而哨兵的中心比标记高 1 个单位,所以如果把高度也算进距离,距离就永远不会小于 1,哨兵也就永远不会掉头。检测条件是距离小于 0.2,而不是刚好等于 0:哨兵每秒移动 2 个单位,每步会移动 0.04 个单位,因此几乎不会刚好停在岗哨上。

challenge icon

挑战

中等

让机器人沿着航点巡逻,并追逐靠近的玩家。

  1. 编写 WalkTo(Vector3 target),让 rb.linearVelocity 在地面上朝目标移动,速度为 speed,同时保持 y 方向的速度。
  2. 在 FixedUpdate() 中,当玩家距离小于 chaseRange 时,调用 WalkTo(player.position) 并执行 return。
  3. 否则,当距离 waypoints[next] 小于 0.2 时,设置 next = (next + 1) % waypoints.Length;,然后朝 waypoints[next] 移动。

按下“开始”,然后穿过它的路径。接着按“检查”。

亲手试试

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()
    {
        // 玩家靠近时追逐玩家,否则沿巡逻路线移动
    }
}

物理与游戏玩法中的所有课

自己练习: Unity 在线编辑器