NPC Motion Solutions
Basic NPC Behaviors:
DESCRIPTION:
This example requires that we flip our direction on collisions. This is a simple example of using a vector to keep track of what direction a character is moving.
KEY CONCEPTS:
using vectors as directions
collision detection
PSEUDOCODE:
let there be a vector2 variable called direction,
let there be a variable called speed,
every fixed update,
on a collision,
This example requires that we flip our direction on collisions. This is a simple example of using a vector to keep track of what direction a character is moving.
KEY CONCEPTS:
using vectors as directions
collision detection
PSEUDOCODE:
let there be a vector2 variable called direction,
with a value of Vector2.right (aka 1,0)
let there be a variable called speed,
every fixed update,
move the ghost in direction by speed
on a collision,
flip direction by multiplying it by 1
DESCRIPTION:
This example requires getting random values , which we can easily accomplish with the Random.Range function. Also check out these other methods for generating random values. Note that picking truly random values looks pretty unnatural or jittery!
KEY CONCEPTS:
Random variables
PSEUDOCODE:
Let there be a variable called speed
every fixed update,
This example requires getting random values , which we can easily accomplish with the Random.Range function. Also check out these other methods for generating random values. Note that picking truly random values looks pretty unnatural or jittery!
KEY CONCEPTS:
Random variables
PSEUDOCODE:
Let there be a variable called speed
every fixed update,
pick a random direction
move the ghost in that direction by speed
DESCRIPTION:
This example requires perlin noise, which is a good way to generate “pseudorandom” values that look natural, not too chaotic or jittery!
KEY CONCEPTS:
perlin noise
PSEUDOCODE:
let there be a variable called speed
let there be a variable called seedX;
let there be a variable called seedY;
when the game starts,
every fixed update,
This example requires perlin noise, which is a good way to generate “pseudorandom” values that look natural, not too chaotic or jittery!
KEY CONCEPTS:
perlin noise
PSEUDOCODE:
let there be a variable called speed
let there be a variable called seedX;
let there be a variable called seedY;
when the game starts,
set seedX to a random decimal value between 0 and 100
set seedY to a random decimal value between 0 and 100
every fixed update,
let there be a new vector2 variable called direction
get a value with perlin noise using seedX and the current time in seconds, and assign it to direction.x
get a value with perlin noise using seedY and the current time in seconds, and assign it to direction.y
move the ghost by direction multiplied by speed
Wandering NPC Behaviors
DESCRIPTION:
This example is tricky because unlike the linear bouncer / goomba, you can’t just flip the direction by multiplying it by 1. Doing so would send the ghost back directly where it came from!
The simplest way to handle this is to flip just one part of the direction vector depending on where the NPC collided with something.
KEY CONCEPTS:
direction vector, contact points, modifying the components of a vector (the x and y values) directly
PSEUDOCODE:
let there be a vector2 variable called direction
let there be a float variable called speed
when the game starts,
pick a diagonal direction to start moving in. for example (1,1), (1,1), and so on
every fixed update,
move the ghost by direction multiplied by speed
on a collision
This example is tricky because unlike the linear bouncer / goomba, you can’t just flip the direction by multiplying it by 1. Doing so would send the ghost back directly where it came from!
The simplest way to handle this is to flip just one part of the direction vector depending on where the NPC collided with something.

If the NPC hit its top or bottom side, flip only the Y axis.
 If the NPC hits its left or right side, flip only the X axis.
KEY CONCEPTS:
direction vector, contact points, modifying the components of a vector (the x and y values) directly
PSEUDOCODE:
let there be a vector2 variable called direction
let there be a float variable called speed
when the game starts,
pick a diagonal direction to start moving in. for example (1,1), (1,1), and so on
every fixed update,
move the ghost by direction multiplied by speed
on a collision
get the contact point of the collision
If the contact point is above or below the ghost, flip direction.y
if the contact point is to the left or right of the ghost, flip direction.x
DESCRIPTION:
I like this behavior for NPCs that wander aimlessly around town, like you might see in any JRPG or adventure game. This example alternates between two states:
We will use the random.range function to pick one of four directions. Random range for integers takes two arguments, a minimum value (inclusive) and a max value (exclusive). To get one of four values at random, we need to then write it like so:
KEY CONCEPTS:
making choices randomly with random.range
timing / delaying with a float timer variable
using a bool to keep track of NPC’s state
PSEUDOCODE:
Let there be a vector2 variable called direction
Let there be a float variable called timer
Let there be a float variable called speed
Let there be a bool variable called isMoving
every fixed update,
if the timer is done and isMoving is false
if isMoving is true
To pick a direction:
I like this behavior for NPCs that wander aimlessly around town, like you might see in any JRPG or adventure game. This example alternates between two states:
 standing still
 moving along a cardinal direction (north south east west), chosen at random
We will use the random.range function to pick one of four directions. Random range for integers takes two arguments, a minimum value (inclusive) and a max value (exclusive). To get one of four values at random, we need to then write it like so:
int choice = Random.Range(0,4);which will return 0, 1, 2, or 3. Computers always start counting at 0!
KEY CONCEPTS:
making choices randomly with random.range
timing / delaying with a float timer variable
using a bool to keep track of NPC’s state
PSEUDOCODE:
Let there be a vector2 variable called direction
Let there be a float variable called timer
Let there be a float variable called speed
Let there be a bool variable called isMoving
every fixed update,
if the timer is done and isMoving is false
pick a direction (see below)else if the timer done and isMoving is true
reset the timer to 1 second
set isMoving to true
reset the timer to 1 secondrun down the timer
set isMoving to false
if isMoving is true
move the ghost by direction multiplied by speed
To pick a direction:
let there be an integer called choice. assign it a random number from 0 (inclusive) to 4 (exclusive)
if choice is 0, set direction to up
if choice is 1, set direction to down
if choice is 2, set direction to left
if choice is 3, set direction to right
DESCRIPTION:
In this example, the ghost turns pseudorandomly with perlin noise, and moves along it’s own “up” axis. When the ghost collides with something, it rotates 180 degrees.
This approach works well for cars, fish, missiles, and more.
KEY CONCEPTS:
Noise, Rotation
PSEUDOCODE:
When the game starts,
Every fixed update,
On a collision,
In this example, the ghost turns pseudorandomly with perlin noise, and moves along it’s own “up” axis. When the ghost collides with something, it rotates 180 degrees.
This approach works well for cars, fish, missiles, and more.
KEY CONCEPTS:
Noise, Rotation
PSEUDOCODE:
 let there be a float variable called maxTurn (in degrees), assign it 360
When the game starts,
 use Rigidbody2D.SetRotation and Random.Range to set the character to a randomized starting rotation
Every fixed update,
 get a noise value with perlinNoise
 remap noise from 0:1 to 1 : 1 by multiplying it by 2 and subtracting 1
 multiply noise by maxTurn to determine how much to rotate the NPC this frame
 use Rigidbody2D.MoveRotation to set the rotation
 move the rigidbody along the NPC’s up vector (transform.up)
On a collision,
Rotate the NPC 180 degrees
Interactive NPC Behaviors
DESCRIPTION:
In this example, the ghost moves towards the player character, and stops when it is touching the player.
We’ll need to determine the direction from the ghost to the player. For that, we can use a little vector math.
Remember, to get a vector going from poitn A to B is B  A!
KEY CONCEPTS:
getting a direction vector from one point to another
PSEUDOCODE:
let there be a bool variable called touching
Every fixed update, if touching is false:
In this example, the ghost moves towards the player character, and stops when it is touching the player.
We’ll need to determine the direction from the ghost to the player. For that, we can use a little vector math.
Remember, to get a vector going from poitn A to B is B  A!
KEY CONCEPTS:
getting a direction vector from one point to another
PSEUDOCODE:
let there be a bool variable called touching
Every fixed update, if touching is false:
Get a a direction vector going from the NPC to the targetOn a collision enter,
if the NPC touched the player character, set touching to trueOn a collision exit,
if the NPC was touching the player character, set touching to false
DESCRIPTION:
This example is similar to the Seeker, with a few differences:
KEY CONCEPTS:
getting direction away from a given point
getting the distance between two points
PSEUDOCODE:
let there be:
every fixed update:
This example is similar to the Seeker, with a few differences:

the NPC moves away from the player
 the NPC only moves when the player is within a certain distance
KEY CONCEPTS:
getting direction away from a given point
getting the distance between two points
PSEUDOCODE:
let there be:
a Vector2 called direction
a public Transform called avoidTarget
a float called avoidThreshold, with a value of 3
a float called speed, with a value of 1
every fixed update:
get a direction vector from the NPC to avoidTarget, and assign that value to a vector2 called toTarget
if the length of toTarget is greater than avoidThreshold:
set direction to (0,0)
else
set direction to toTarget.normalized * 1 (this creates a vector with a length of one, pointing away from the target)
move the npc by direction multiplied by speed
DESCRIPTION:
Companion is a combination of Seeker and Avoider, where the NPC tries to stay a specific distance away from the player.
KEY CONCEPTS:
direction vectors
distance between two points
PSEUDOCODE:
let there be a public float called followDistance
let there be a public Transform called followTarget
every fixed update,
Companion is a combination of Seeker and Avoider, where the NPC tries to stay a specific distance away from the player.
KEY CONCEPTS:
direction vectors
distance between two points
PSEUDOCODE:
let there be a public float called followDistance
let there be a public Transform called followTarget
every fixed update,
get the distance between the NPC and followTarget
if the distance is greater than followDistance,
move towards followTarget
if the distance is less than followDistance,
move away from followTarget
DESCRIPTION:
Blade trap is essentially a linear bouncer / goomba behavior that only “goes” when something moves through a trigger attached to the NPC. It has two states:
NOTE that this NPC will need a trigger volume attached to it. I used a box collider that is offset from the NPC’s body
KEY CONCEPTS:
using triggers with npcs
complex behaviors with multiple states
collision detection
PSEUDOCODE:
Let there be:
a Vector2 called startPosition
a public Vector2 called direction, assign this in the editor to determine which way the ghost will go
a float called attackSpeed, set to a high value
a float called retreatSpeed, set to a small value
a bool called running, set to false
When the game starts,
every fixed update,
when an object is within the trigger, (ontriggerstay2D)
when the NPC collides with something
Blade trap is essentially a linear bouncer / goomba behavior that only “goes” when something moves through a trigger attached to the NPC. It has two states:
 Rest: the
NPC
slowly returns to its starting position and waits there
 Attack: the NPC rushes forward until it collides with something
NOTE that this NPC will need a trigger volume attached to it. I used a box collider that is offset from the NPC’s body
KEY CONCEPTS:
using triggers with npcs
complex behaviors with multiple states
collision detection
PSEUDOCODE:
Let there be:
a Vector2 called startPosition
a public Vector2 called direction, assign this in the editor to determine which way the ghost will go
a float called attackSpeed, set to a high value
a float called retreatSpeed, set to a small value
a bool called running, set to false
When the game starts,
assign the NPC’s current position to startPosition
every fixed update,
if running is true
move the ghost along direction
else
move the ghost towards its starting position
when an object is within the trigger, (ontriggerstay2D)
if NPC is close to the starting position, and running is false,
set running to true
when the NPC collides with something
if running is true
set running to false