NPC cannot catch up to player

I’m trying to make an NPC that chases player. The code below is simplified for testing purposes, however the problem is still there. Basically, the NPC catches up until it’s close to the player, then it’ll just stutter behind him without ever reaching. This happens even at very high walkspeed.
I’ve already tried to set the owner ship to nil and it didn’t change anything. I even use the second parameter of MoveTo in the hopes of it fixing anything (which it didn’t).
I’m at a loss, please help.

https://gyazo.com/e8c4c1e5a5db8dd29bf5238d1e2bad2e

local player = game.Players:WaitForChild("MisterGamer_67")

function entity.Move(model)
	repeat wait() until player.Character
	local humanoid = player.Character:FindFirstChild("Humanoid")

	RunService.Heartbeat:Connect(function()		
		if humanoid and humanoid.Health > 0 then
			model.Humanoid:MoveTo(player.Character.PrimaryPart.Position, player.Character.PrimaryPart)
		end
	end)
end
2 Likes

I believe the issue is because the NPC wants to get to the point but it also wants to avoid physics obstacles which in this case is the player itself. Maybe you can make the target position be behind the player and then change it closer to the player the closer the NPC is to them.

1 Like

Honestly this seems a bit overcomplicated for the task.
The kind of behavior I’m trying to produce is seen in a lot of experiences (literally every zombie game, even the classic roblox games).
It looks like some odd behavior from the client, as MoveTo() should work as intended, even with the player’s physics.

1 Like

im not sure what you are trying to get here but i did something where if the npc gets 2 studs close it reduces it speed…

local player = game.Players:WaitForChild("MisterGamer_67")

function entity.Move(model)
	repeat wait() until player.Character
	local humanoid = player.Character:FindFirstChild("Humanoid")

	RunService.Heartbeat:Connect(function()		
		if humanoid and humanoid.Health > 0 then
			local distance = (model.PrimaryPart.Position - player.Character.PrimaryPart.Position).Magnitude
			if distance <= 2 then
				humanoid.WalkSpeed = 10
			else
				humanoid.WalkSpeed = 16
			end
			model.Humanoid:MoveTo(player.Character.PrimaryPart.Position, player.Character.PrimaryPart)
		end
	end)
end
1 Like

You can watch this video and check out the script they give. You might consider not using the heartbeat function and just going with a while loop as most of the scripts I’ve seen use that instead.

1 Like

The reason I set the owner ship to the server (nil) is to provent stuttering when the NPC gets close to the player. I’d prefer not changing the player’s speed as it seems more of bandaid than a real solution.

1 Like

Thanks for the recommendation, however the issue is the exact same, even when using this exact script. It may look slightly better but the player can STILL escape the NPC even when its walkspeed is double the one of the player. The person in the video isn’t demonstrating this by walking forward constantly, but I suspect the same issue would occur.

1 Like

Thanks for your reply, however it does not seem to solve my situation.
What’s happening it seems is that since the NPC’s network owner is the server, there is a slight delay with the actual position of the client.
In the gif I sent, the NPC bouncing is because he’s actually colliding with the player on the server, as intended. But this does not replicate properly. Here is a comparison between the server and client :

https://gyazo.com/c5560a35cd41f0ede7e18f4d86ed5e67

1 Like

Well You need to check the difference in how Long the delay from the client to server actually is and then send it to the client or to all clients to fix it visually; where you can define a small single part as the zombie. Or just do it on the one client setting the position a bit more forward by checking the delay with this:

--Server:
RemoteEvent:Fire(player,workspace:GetServerTimeNow() )-- gets it pretty precise
-- Client:
RemoteEvent.Connect(function(ServerTime)
local CurrentClientTime = workspace:GetServerTimeNow()
local Difference = ServerTime - CurrentClientTime
end)