Enemy movement from waypoint to waypoint

I’m going to start programming my Enemy AI and AI is such a large topic that it could be a degree course itself. I’m working by checkpoints and my first and probably i believe one of the hardest things in the whole Enemy AI process is the movement of the NPC.

I’ve noted how I want my NPC’s to be moving and how they make theirs decisions on the next waypoint destination:

Enemy Movement

// Waypoint targets control movement or next destination
// meaning to go left ,right,forward or backwards,
// some type of random function to determine next destination

//when hitting waypoint target idle state and perform
// thinking/idle time before moving towards next destination
// Use distance to next waypoint to determine next destination
// and also implement this with a random feature so its not
// predictable
// contain maybe an array or list of 3 or 4 closest destination
//points

What things do yo suggest? Either examples to look at or any websites or such to have a better idea

Can you clarify your question a bit further? For instance, do you wish your NPCs to visit a set of waypoints at random, or visit the waypoints according to distance, or some combination (such as finding the closest waypoint, then randomly visiting a subset of waypoints within a certain range, etc.)? You mention selecting waypoints at random, but also determining them by distance.

Oh and on line 20 for the C# script if(currentWaypoint < waypoint.length){ ) should be if(currentWaypoint < waypoint.Length){

3 Answers

3

This might help you get started, you can modify it to suit your needs, make sure your enemy has a character controller attached …

Create some empty game objects, name them something like Waypoitn1, Waypoint2 … ect … ect then drop them into the Waypoint in the inspector, tick loop if you want the enemy to keep patrolling when they get to the last Waypoint …

#pragma strict

var waypoint : Transform[];			// The amount of Waypoint you want
var patrolSpeed : float = 3;		// The walking speed between Waypoints
var loop : boolean = true;			// Do you want to keep repeating the Waypoints
var dampingLook = 6.0;				// How slowly to turn
var pauseDuration : float = 0;		// How long to pause at a Waypoint

private var curTime : float;
private var currentWaypoint : int = 0;
private var character : CharacterController;

function Start(){

    character = GetComponent(CharacterController);
}

function Update(){

	if(currentWaypoint < waypoint.length){
		patrol();
		}else{	
	if(loop){
		currentWaypoint=0;
        } 
	}
}

function patrol(){

        var target : Vector3 = waypoint[currentWaypoint].position;
        target.y = transform.position.y; // Keep waypoint at character's height
        var moveDirection : Vector3 = target - transform.position;

	if(moveDirection.magnitude < 0.5){
		if (curTime == 0)
			curTime = Time.time; // Pause over the Waypoint
		if ((Time.time - curTime) >= pauseDuration){
			currentWaypoint++;
			curTime = 0;
		}
	}else{        
		var rotation = Quaternion.LookRotation(target - transform.position);
		transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * dampingLook);
		character.Move(moveDirection.normalized * patrolSpeed * Time.deltaTime);
	}	
}

Yeah this is a great starting point for me to build on its a simple patrol system which i can tweak and its not even that much code as well thanks !

Glad to help.

Is there a way to do this without a CharacterController?

I tried this script but once enemy reaches the waypoint it starts circling continuously on its own orbit.

Hi I know this forum probably hasn't been used in years, but I'm using this script for a little project of mine. I created a pyramid using cubes and set up waypoints on different cubes. I want two enemies to travel down the pyramid, but whenever I hit play, my enemies still follow the path of the waypoints, however they don't go on the cubes, they float in mid air. Thoughts?

var Player:Transform;
var PlayerDistance:float;

var StopRange:float;
var ChaseRange:float;
var AttackRange:float;

var Speed:float;
var RotationSpeed:float;

var waypoint : Transform;
var currentWaypoint : int;

function Start ()
{
Player = GameObject.FindWithTag(“Player”).transform;
currentWaypoint=Random.Range(0,waypoint.Length);
}

function Update ()
{
PlayerDistance = Vector3.Distance(Player.position, transform.position);
if(PlayerDistance<=AttackRange)
{
animation.Play(“attack1”);

}
if(PlayerDistance<=StopRange)
{
	Speed=0;
}
	if(PlayerDistance>=StopRange)
{
	Speed=10;
	animation.Play("run");
}

if(PlayerDistance<ChaseRange)
{
	transform.Translate(Vector3.forward * Speed *Time.deltaTime);
	var Rotation= Quaternion.LookRotation(Player.position - transform.position);// Look at the Players position
	transform.rotation = Quaternion.Slerp(transform.rotation, Rotation, Time.deltaTime*RotationSpeed);

}
if(PlayerDistance>ChaseRange)
{
	animation.Play("run");
	transform.LookAt(waypoint[currentWaypoint].transform);
	if(currentWaypoint < waypoint.length)
    {
        var target : Vector3 = waypoint[currentWaypoint].position;
        var moveDirection : Vector3 = target - transform.position;
        var velocity = rigidbody.velocity;    
        if(moveDirection.magnitude < 15){currentWaypoint=Random.Range(0,waypoint.Length);}else{velocity = moveDirection.normalized*Speed;}}
    	rigidbody.velocity = velocity;
    	//if(currentWaypoint == waypoint.length){currentWaypoint=Random.Range(0,waypoint.Length);}
}

}

This site has helped me a lot with my AI questions…

http://www-cs-students.stanford.edu/~amitp/gameprog.html

Sorry I cannot help further.