NPC can't catch up to a player close enough

I want to make a similar game to “Zombie Rush” or “Zombie Attack” and currently I’m working on the zombie AI.

The issue

The issue however, is that the zombie does successfully get to me (the closest player) but he doesn’t get “close enough” by that I mean touching my Torso.

I have given the zombie 30 walk speed (default is 16) to demonstrate what is happening.

In the video above you can see the zombie quickly moving to me (the nearest player) and at around 6 studs away from me he starts moving at the same pace as me. (keep in mind that the zombie is almost double as fast as me)

What I want to Achieve

I want to make the zombie be able to fully catch up to me and “attack” me (as in just touching me).

What I have been able to do

I tried looking for solutions in the past, however I haven’t found any solution that has satisfied me yet.

I even tried making the zombie move to a position in front of me by a couple of studs, but this didn’t really work either.

In the script below I have a function to move to the nearest player and what that function does is it ray casts to the targeted player to check if path finding is necessary.

local players = game.Players

local zombie = script.Parent

local humanoid = zombie.Humanoid
local humanoidRootPart = zombie.HumanoidRootPart

local runService = game:GetService("RunService")

local baseparts = zombie:GetChildren()

for _, basepart in pairs(baseparts) do
	if basepart:IsA("BasePart") then
		basepart:SetNetworkOwner(nil)
	end
end

local function findNearestPlayer ()
	local allPlayers = players:GetPlayers()
	
	local nearestPlayer = nil
	local nearestMagnitude = math.huge
	
	for _, player in pairs(allPlayers) do
		local character = player.Character or player.CharacterAdded:Wait()
		local magnitude = (character.HumanoidRootPart.Position - humanoidRootPart.Position).Magnitude
		
		if magnitude < nearestMagnitude then nearestPlayer = character nearestMagnitude = magnitude end
	end
	
	return nearestPlayer
end

local function rayCastToPlayer (raydestination, rayparms)
	local rayorigin = humanoidRootPart.Position
	local rayDirection = (raydestination - rayorigin).Unit
	
	local raycast = workspace:Raycast(rayorigin, rayDirection * (rayorigin - raydestination).Magnitude, rayparms)
	
	return raycast
end

local function moveToPlayer (target)
	local rayParams = RaycastParams.new()
	rayParams.FilterType = Enum.RaycastFilterType.Blacklist
	rayParams.FilterDescendantsInstances = {baseparts}
	
	local needToPathfind = true
	
	local rayCast = rayCastToPlayer(target.HumanoidRootPart.Position, rayParams)
	if rayCast and rayCast.Instance.Parent == target then needToPathfind = false end	
	
	
	if needToPathfind then
		local path = game.PathfindingService:CreatePath({
			AgentRadius = 2,
			AgentHeight = 4,
			AgentCanJump = true
		})

		path:ComputeAsync(humanoidRootPart.Position, target.HumanoidRootPart.Position)

		if path.Status == Enum.PathStatus.Success then
			local waypoints = path:GetWaypoints()
			if waypoints and waypoints[2] then
				local data = waypoints[2]
				humanoid:MoveTo(data.Position)
			end
		end
	else
		humanoid:MoveTo(target.HumanoidRootPart.Position)
	end
end

runService.Heartbeat:Connect(function()
	local nearestPlayer = findNearestPlayer()
	
	if nearestPlayer then moveToPlayer(nearestPlayer) end
end)

Any help would be great!

Please convert the video to mp4 or record with something other than roblox.

Sorry! Should have been fixed now!

1 Like

I think maybe it has to do with this property.

1 Like

Hmmm… I removed the agent params from the path finding… Nothing changed

1 Like

Inside the moveToPlayer function where you move the humanoid directly to the player’s HumanoidRootPart Position you can pass as a second argument the HumanoidRootPart as the part it’s trying to achieve, here is a screenshot from the humanoid documentation:

3 Likes

Yep! This certainly does solve my problem!

Thanks for everyone trying to help!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.