Following waypoints in a sequence

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.

Following waypoints in a sequence

Getting ready

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.

How to do it...

To follow waypoints in a sequence, perform the following steps:

  1. Create a sphere named Arrow, positioned at (2, 0.5, 2) and with scale (1, 1, 1).
  2. Create a second sphere, named Sphere-small, positioned at (2, 0.5, 2.5) and with scale (0.5, 0.5, 0.5).
  3. Make Sphere-small a child-object of your GameObject Arrow.
  4. Create a new capsule object named Capsule-waypoint-0 at (-12, 0, 8), give it the tag waypoint.
  5. Copy Capsule-spawnPoint-0 naming the copy Capsule-spawnPoint-1 and positioning this copy at (0, 0, 8).
  6. Make four more copies (named 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)
  7. Add the following C# script class to GameObject 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];
      }
    }
  8. Add the following script class to GameObject 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 );
      }
    }
  9. With Arrow selected in the Hierarchy panel, in the Waypoint Manager scripted component in the Inspector, do the following:
    • Set the size of the Waypoints public array to 6
    • Drag the six capsule waypoint objects into the array in sequence
    How to do it...

How it works...

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 target
  • speed: 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 towards
  • waypointManager: This is a reference to the WaypointManager object in the parent (Arrow) GameObject

When 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.

See also

  • The Finding a random spawn point recipe
  • The Finding the nearest spawn point recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.137.117