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
MediumMake the robot patrol its waypoints and chase the player who comes close.
- Write
WalkTo(Vector3 target), settingrb.linearVelocitytoward it across the ground atspeed, keeping its y velocity. - In
FixedUpdate(), when the player is closer thanchaseRange,WalkTo(player.position)andreturn. - Otherwise, under 0.2 from
waypoints[next], setnext = (next + 1) % waypoints.Length;, then walk towaypoints[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
1Rigidbody
Gravity and MassPush with AddForceJump with an ImpulseFixedUpdate for PhysicsVelocityKinematic BodiesRecap: Launch Pad4Coroutines
InvokeInvokeRepeating, CancelInvokeYour First CoroutineLoops in CoroutinesStopping CoroutinesRecap: Countdown10Project: Arena Escape
The ArenaHunters2Collisions
OnCollisionEnterWhat Did I Hit?Break on ImpactStanding on the GroundBounce and FrictionCollider ShapesRecap: Breakable Wall3Triggers
Trigger CollidersOnTriggerEnterPickupsCrates Keep the RestKill ZonesEnter and ExitRecap: Key and Door6Raycasts
Physics.RaycastRaycastHitGround Check with a RayLayers and LayerMaskLine of SightOverlapSphere and SphereCastRecap: Laser Tripwire9Enemies
Chase the PlayerChase in RangePatrol and ChaseHealth and DamageBullets That HitKnockbackRecap: Guard DogPractice on your own: Unity playground