How to make killer npc that catches up with player

Hi I made a game and there is killer NPC who’s faster than you, but he is very far behind. A few people have told me that it’s because of desync, but what should I do to make it so that it chases you like in other horror games? Thanks :smile:


The npc runs on a simple “Magnitude/MoveTo” npc script.

1 Like

is the moveto in a while loop?

3 Likes

yeah, it uses a while loop to when moving to player

local speedy = script.Parent
local SpeedyHum = speedy.Humanoid
local SpeedyTorso = speedy.Torso

local function search ()
	local KillDistance = 70
	local Victim
	
	for i, v in pairs(game.Workspace:GetChildren()) do
		local PlrHum = v:FindFirstChild("Humanoid")
		local plrTors = v:FindFirstChild("Torso")
		
		if PlrHum and plrTors and v ~= script.Parent then
			if (plrTors.Position - SpeedyTorso.Position).Magnitude <= KillDistance then
				KillDistance = (plrTors.Position - SpeedyTorso.Position).Magnitude
				Victim = plrTors
			end
		end
	end
	return Victim
end

while wait() do
	local plrTors = search()
	if plrTors then
		SpeedyHum:MoveTo(plrTors.Position)
	else
		task.wait(1)
		SpeedyHum:MoveTo(SpeedyTorso.Position + Vector3.new(math.random(-30,30),0,math.random(-30,30)))
	end
end

First of all, I’ve noticed that you use wait() and task.wait(). I suggest moving wait() to task.wait(). Also, after declaring SpeedyHum:MoveTo(plrTors.Position), i would add SpeedyHum.MoveToFinished:Wait(), so it waits for the movement to be done then it continues. Lastly, what is the else in the while loop for?

I’ve done the :MoveToFinished:Wait() Part, but it made him stand still.

EDit: Wait nevermind, I spelled it wrong in the code, Lol

I tried it, but it just makes him stand still. I think i’ve done it wrong so I’ll put the code here:

while task.wait() do
	local plrTors = search()
	if plrTors then
		SpeedyHum:MoveTo(plrTors.Position)
		SpeedyHum.MoveToFinished:Wait()
	else
		task.wait(1)
		SpeedyHum:MoveTo(SpeedyTorso.Position + Vector3.new(math.random(-30,30),0,math.random(-30,30)))
	end
end

Also, a more efficient way of using :MoveTo() is using PathFindingService to calculate a efficient path, and so it moves even if there is a wall blocking it, it would just go around the wall. It has the same deal, but you may need another local function for this. Most horror games use this service for chases.

1 Like

Ah, alright. I was thinking that, but I didn’t know if I could do it. I’ll try it though!