Chase in Range
Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 53 of 71.
Most enemies leave you alone until you come close. Measure the distance to the player in every physics step, and chase only inside a range. This slime chases within sightRange and stands still outside it:
void FixedUpdate()
{
Vector3 toPlayer = player.position - rb.position;
toPlayer.y = 0f;
if (toPlayer.magnitude < sightRange)
{
Vector3 dir = toPlayer.normalized;
rb.linearVelocity = new Vector3(dir.x * speed, rb.linearVelocity.y, dir.z * speed);
}
else
{
rb.linearVelocity = new Vector3(0f, rb.linearVelocity.y, 0f);
}
}The else matters: a Rigidbody keeps its velocity until something changes it. Without it, a slime that loses you slides on until friction stops it, and on ice it never stops. Because y was set to 0 first, toPlayer.magnitude is the distance across the ground, so a player standing on a crate next to the slime still counts as next to it.
One range has a weak spot. A player standing on its edge drifts in and out of it, and the slime starts and stops over and over. Enemies avoid this with two ranges: they notice the player inside a short one and give up only beyond a longer one. A bool remembers whether the enemy is chasing, and between the two ranges nothing changes it, so the enemy carries on with what it was doing.
Challenge
MediumMake the wolf notice the player close up and give up far away.
- In
FixedUpdate(), take the flat distance to the player: undernoticeRange, set thebool chasingfieldtrue; overgiveUpRange,false. - While
chasing, setrb.linearVelocitytoward the player atspeed, keeping its y. - Otherwise set
rb.linearVelocity = new Vector3(0f, rb.linearVelocity.y, 0f);.
Press Play, walk up to the wolf and run. Then Check.
Try it yourself
using UnityEngine;
public class Wolf : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private float speed = 3f;
[SerializeField] private float noticeRange = 4f;
[SerializeField] private float giveUpRange = 8f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
// notice the player, give up on it, and chase or stand still
}
}
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 WallPractice on your own: Unity playground