How to make a NPC walk along a sidewalk?

I’m trying to get an npc to walk around on a set path similar to a sidewalk sort of like npcs do in gta but I can’t quite figure out how to make them walk around randomly on the entire thing.

I found this post: How do I make NPCs that randomly walk around on a path?
and the solution to it said to use something called adjacency lists but I couldn’t figure out how to use that.

I ended up using this code inside the NPC:

local NPC = script.Parent
local WalkPoints = game.Workspace.WalkPoints
local lastPoint = nil
local lastPoint2 = nil
local lastPoint3 = nil
NPC.PrimaryPart:SetNetworkOwner(nil)

local function getAdjacentPoints()
	local maxDistance = 100
	local point
	for _, value in pairs(WalkPoints:GetChildren()) do
		if value ~= lastPoint and value ~= lastPoint2 and value ~= lastPoint3 then
			local distance = (NPC.HumanoidRootPart.Position - value.Position).Magnitude
			if distance < maxDistance then
				maxDistance = distance
				point = value
			end
		end
	end	
	
	return point
end

while true do
	local Point = getAdjacentPoints()
	lastPoint3 = lastPoint2
	lastPoint2 = lastPoint
	lastPoint = Point
	NPC.Humanoid:MoveTo(Point.Position)
	NPC.Humanoid.MoveToFinished:Wait()
end

and I’ve set the map up like this:
image

and it seemed to accomplish what I wanted up until it was just running in circles on the left and never touched the 3 points on the right. If you would like to test it, the half transparency parts are in a folder in the workspace called “WalkPoints”. If anyone could help me figure out how to make them walk around randomly and walk to all the points that would be much appreciated!

3 Likes

is the if distance statement intentional?

2 Likes

Yes, I added the distance statement so the NPC finds the closest points rather than on really far away and they walk off the sidewalk

2 Likes

UPDATE: So I’ve been trying to work this out and I’ve changed the code to this:

local NPC = script.Parent
local WalkPoints = game.Workspace.WalkPoints
local lastPoint = nil
local lastPoint2 = nil
local points = {}
NPC.PrimaryPart:SetNetworkOwner(nil)

local function getAdjacentPoint()
	local maxDistance = 100
	local point
	for _, value in pairs(WalkPoints:GetChildren()) do
		if value ~= lastPoint and value ~= lastPoint2 and not table.find(points, value) then
			local distance = (NPC.HumanoidRootPart.Position - value.Position).Magnitude
			if distance < maxDistance then
				maxDistance = distance
				point = value
			end
		end
	end	
	
	return point
end

local function getPoint()
	points = {}
	repeat table.insert(points, getAdjacentPoint()) until #points == 2
	local point = points[math.random(1,#points)]
	return point
end

while true do
	local Point = getPoint()
	lastPoint2 = lastPoint
	lastPoint = Point
	NPC.Humanoid:MoveTo(Point.Position)
	NPC.Humanoid.MoveToFinished:Wait()
end

And the only issue I’m running into now is that the npc occasionally walks off the path to reach a point rather than staying on the sidewalk. If anyone has a solution to this I would appreciate this!

2 Likes

i dont know how to code my solution but try to add like an invisible part below the sidewalk like so:

the sidewalk is the blue part and the grey block is the invisible part. dont mind my building demo btw lmao :laughing:

if the npc touch the invis part, the npc will have to check the nearest point near him but make sure the npc do not go back to the spot he came from.

my second solution is you can use pathfinding. similar to my first solution, you’ll need to use an invisible wall. Here are sources if you want to switch to this method:

Pathfinding (roblox.com)

hope this helps!

1 Like

I’ll probably have to end up trying to use pathfinding because the NPC walking on the sidewalk is just an idle action but eventually they will go off of it to do something like follow the player.

1 Like