Waypoints are often used as a guide to make an autonomously moving NPC follow a path in a general way (but be able to respond with other directional behaviors, such as flee or seek, if predator/prey is sensed nearby). The waypoints are arranged in a sequence, so that when the character reaches or gets close to a waypoint, it will then select the next waypoint in the sequence as the target location to move towards. This recipe demonstrates an Arrow
object moving towards a waypoint, and then when it gets close enough, choosing the next waypoint in the sequence as the new target destination. When the last waypoint has been reached, it starts again heading towards the first waypoint.
This recipe builds upon the player-controlled cube Unity project you created in a previous recipe. So make a copy of that project, open it, and then follow the steps of this recipe.
To follow waypoints in a sequence, perform the following steps:
Arrow
, positioned at (2, 0.5, 2) and with scale (1, 1, 1).Sphere-small
, positioned at (2, 0.5, 2.5) and with scale (0.5, 0.5, 0.5).Sphere-small
a child-object of your GameObject Arrow
.Capsule-waypoint-0
at (-12, 0, 8), give it the tag waypoint
.Capsule-spawnPoint-0
naming the copy Capsule-spawnPoint-1
and positioning this copy at (0, 0, 8).Capsule-spawnPoint-2.5
) positioning them as follows:Capsule-spawnPoint-2
: Position set as (12, 0, 8)Capsule-spawnPoint-3
: Position set as (12, 0, -8)Capsule-spawnPoint-4
: Position set as (0, 0, -8)Capsule-spawnPoint-5
: Position set as (-12, 0, -8)Arrow
:// file: WaypointManager.cs using UnityEngine; using System.Collections; public class WaypointManager : MonoBehaviour { public GameObject[] waypoints; public GameObject NextWaypoint(GameObject current){ if( waypoints.Length < 1) print ("ERROR - no waypoints have been added to array!"); // default is first in the array int nextIndex = 0; // find array index of given waypoint int currentIndex = -1; for(int i = 0; i < waypoints.Length; i++){ if( current == waypoints[i] ) currentIndex = i; } int lastIndex = (waypoints.Length - 1); if(currentIndex > -1 && currentIndex < lastIndex) nextIndex = currentIndex + 1; return waypoints[nextIndex]; } }
Arrow
:// file: MoveTowardsWaypoint.cs using UnityEngine; using System.Collections; public class MoveTowardsWaypoint : MonoBehaviour { public const float ARRIVE_DISTANCE = 3f; public float speed = 5.0F; private GameObject targetGO; private WaypointManager waypointManager; private void Awake(){ waypointManager = GetComponent<WaypointManager>(); targetGO = waypointManager.NextWaypoint(null); } private void Update () { transform.LookAt( targetGO.transform ); float distance = speed * Time.deltaTime; Vector3 source = transform.position; Vector3 target = targetGO.transform.position; transform.position = Vector3.MoveTowards(source, target, distance); if( Vector3.Distance( source, target) < ARRIVE_DISTANCE) targetGO = waypointManager.NextWaypoint( targetGO ); } }
The WaypointManager
class has an array waypoints
, and a method NextWaypoint()
. The array is public, and via the inspector we have assigned the waypoint GameObjects in sequence to this array. The NextWaypoint()
method takes as input a GameObject (or null), and returns a GameObject. The input is a waypoint, and the return value is the next waypoint GameObject in the array sequence, or the first in the array if the input object cannot be found.
The MoveTowardsWaypoint
class has the following four variables:
ARRIVE_DISTANCE
: This is the distance from a waypoint, at which point the Arrow
will then choose the next waypoint as its targetspeed
: This is the distance to be travelled in each second (so as usual it will be multiplied by Time.deltaTime
for the distance per frame)targetGO
: This is the GameObject of the current target waypoint object to move towardswaypointManager
: This is a reference to the WaypointManager
object in the parent (Arrow
) GameObjectWhen an Awake()
message is received, the waypointManager
object is assigned to the WaypointManager
in the Arrow
object, and targetGO
is set to be the first waypoint in the sequence (by sending the argument of null
, the first waypoint in the array will always be returned).
The Update()
method is responsible for making the Arrow
object move towards the location of targetGO
. It does this making use of the MoveTowards()
method of Vector3
. The final statement in the method then tests whether the current targetGO
has been reached (distance is less than ARRIVE_DISTANCE
). Once it has been reached, then targetGO
is reassigned to the next waypoint in the sequence.
52.14.82.217