Chase the Player
Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 52 of 71.
An enemy that chases the player needs a Rigidbody, so walls stop it and it can push and be pushed. The chase itself is a velocity aimed at the player, set once per physics step. This zombie walks toward whatever is in its player slot:
[SerializeField] private Transform player;
[SerializeField] private float speed = 2.5f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
Vector3 toPlayer = player.position - rb.position;
toPlayer.y = 0f;
Vector3 dir = toPlayer.normalized;
rb.linearVelocity = new Vector3(dir.x * speed, rb.linearVelocity.y, dir.z * speed);
}player.position - rb.position points from the zombie to the player. Its y is set to 0 so the zombie walks level when the player stands higher or lower, and normalized gives it length 1, so the zombie walks at speed whether the player is 2 units away or 20. The new velocity keeps the old y velocity, so gravity still pulls the zombie down off a step. Its Rigidbody has Freeze Rotation on, so it does not tip over as it walks.
A velocity you set makes a walker that starts and turns at once. A heavy enemy, such as a rolling barrel, is pushed with AddForce in the same FixedUpdate instead: it gathers speed, keeps its momentum and overshoots when the player steps aside.
Vector3 toPlayer = player.position - rb.position;
toPlayer.y = 0f;
rb.AddForce(toPlayer.normalized * push);Avoid moving a chaser's Transform: that places it inside a wall as readily as anywhere else, and the physics engine can only push it back out afterwards.
Challenge
MediumMake the boulder roll after the player.
- In
FixedUpdate(), setVector3 toPlayer = player.position - rb.position;andtoPlayer.y = 0f;, so the push stays along the ground. - Call
rb.AddForce(toPlayer.normalized * force);, the same push near or far. Leave its rotation free, so friction rolls it.
Press Play and run circles around the boulder. Then Check.
Try it yourself
using UnityEngine;
public class Boulder : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private float force = 6f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
// push the boulder toward the player, along the ground
}
}
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