Menu
CoddyTech

Patrol and Chase

Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 54 of 71.

A guard on patrol walks a route until it sees the player, chases, and goes back to its route once the player is gone. Both behaviors steer the same way, toward a point, so one method can do the walking for both. This sentry walks back and forth between two posts and chases the player within 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);
}

The chase test comes first, and its return skips the patrol code, so chasing wins whenever the player is close. goal is a field, so the sentry remembers it through a chase: once the player is gone, it walks on to the post it was heading for.

The arrival test measures across the ground. The posts are markers on the floor and the sentry's center is 1 unit above them, so a distance with the height in it never drops below 1 and the sentry would never turn around. The test asks for less than 0.2, not exactly 0: at 2 units per second the sentry moves 0.04 units per step and almost never lands exactly on the post.

challenge icon

Challenge

Medium

Make the robot patrol its waypoints and chase the player who comes close.

  1. Write WalkTo(Vector3 target), setting rb.linearVelocity toward it across the ground at speed, keeping its y velocity.
  2. In FixedUpdate(), when the player is closer than chaseRange, WalkTo(player.position) and return.
  3. Otherwise, under 0.2 from waypoints[next], set next = (next + 1) % waypoints.Length;, then walk to waypoints[next].

Press Play and cross its path. Then Check.

Try it yourself

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()
    {
        // chase the player when it is close, or walk the patrol route
    }
}

All lessons in Physics and Gameplay

Practice on your own: Unity playground