Moving NPCs Between Points
Moving NPCs Between Points
NPCs, or non-player characters, can add a lot of depth to a game. NPCs can be enemies for players to fight, colorful characters that players can talk to and interact with, and more.
Sometimes an NPC can stand in one place, like a shopkeeper working at a small in-game shop. In other cases, an NPC will look much less robotic (and more human!) if it moves around, even if it’s basic movement between two or more points.
Moving to a Point
A simple way to move an NPC is with the
Humanoid object, a special object that gives a
Model|model the functionality of a character, even if it doesn’t look human. This allows the model to physically move around the place and interact with objects in it.
Consider this zombie. Zombies aren’t very smart, so we can make it walk in a straight line without worrying if anything is in the way.
For convenience, the green flag model inside the game has been named GreenFlag. We’ll use it as the first destination for the zombie to walk to. Consider this example:
-- Variables for the zombie and its humanoid local zombie = game.Workspace.Zombie local humanoid = zombie.Humanoid -- Variables for the point(s) the zombie should move between local pointA = game.Workspace.GreenFlag -- Move the zombie to the primary part of the green flag model humanoid:MoveTo(pointA.PrimaryPart.Position)
In this basic code, we find the Zombie model in the workspace, get its
Humanoid object, set the green flag as the destination point, and then tell the zombie to walk toward it using the
Moving to Additional Points
Moving an NPC to one point is cool, but what about moving it in a series of points? You could script a bunch of
wait() commands in a sequence, but that’s tedious to code.
A better solution is to use the
Humanoid/MoveToFinished|MoveToFinished event. This event lets you pause a script until the
Humanoid/MoveTo|MoveTo() action is completed and the NPC reaches its destination. Then you can continue running the script, moving the NPC onward to another point or back to its original point.
In the following code, we create another variable,
pointB, for the purple flag. Immediately after sending the zombie toward the green flag, we pause the script. Once it reaches that flag, the script continues and we send the zombie moving toward the purple flag.
-- Variables for the zombie and its humanoid local zombie = game.Workspace.Zombie local humanoid = zombie.Humanoid -- Variables for the point(s) the zombie should move between local pointA = game.Workspace.GreenFlag local pointB = game.Workspace.PurpleFlag -- Move the zombie to the primary part of the green flag model humanoid:MoveTo(pointA.PrimaryPart.Position) -- Wait until the zombie has reached its first target humanoid.MoveToFinished:Wait() -- Move the zombie to the primary part of the purple flag model humanoid:MoveTo(pointB.PrimaryPart.Position)
DataType/RBXScriptSignal|Connectto call a custom function when the event occurs. In this example, we just need to pause the script until the
Humanoid/MoveToFinished|MoveToFinishedevent fires, and that's exactly what an event’s
Cycling Between Points
Now that the zombie moves between the two flags, let’s finish up this script by adding:
- A loop which makes the zombie continually patrol back and forth between the flags.
- A customizable “patrol delay” which makes the zombie pause for a short time before moving to the next point.
-- Set patrol delay at 2 seconds local PATROL_DELAY = 2 -- Variables for the zombie and its humanoid local zombie = game.Workspace.Zombie local humanoid = zombie.Humanoid -- Variables for the point(s) the zombie should move between local pointA = game.Workspace.GreenFlag local pointB = game.Workspace.PurpleFlag -- Variable to keep track of the zombie's next destination local nextDestinationObject = pointA -- Loop to move between the two points while wait(PATROL_DELAY) do -- Move the zombie to the next destination humanoid:MoveTo(nextDestinationObject.PrimaryPart.Position) -- Wait until the zombie has reached its target humanoid.MoveToFinished:Wait() -- Switch the current target to the other target if nextDestinationObject == pointA then nextDestinationObject = pointB else nextDestinationObject = pointA end end
That’s it! Now the zombie patrols between the flags, stopping to rest for 2 seconds each time.
Where next? As you can see, straight-line movement between points is simple but it’s also limiting. If any obstacle exists on the path (wall, river, cliff, etc.), the NPC might never reach its destination. Zombies don’t have big brains, but other NPCs should act “smarter” and try to find the best path to a destination. Learn how in the