Enemy NPC not close enough to player

This NPC struggles to close gaps with players.

Current code:

local Service = game:GetService("PathfindingService")
local Human = script.Parent.Humanoid
local Torso = script.Parent.Torso

script.Parent.HumanoidRootPart:SetNetworkOwner(nil)

local Target = nil

local counter = 0

local path = Service:CreatePath({
	AgentRadius = 4,
	AgentHeight = 6,
	AgentCanJump = true,
	AgentCanClimb = true
})

local function getTarget()
	
	counter = 0
	
	local Players = game.Players:GetPlayers()

	for i, player in pairs(Players) do
		print(player.Name)
		if player.Character then
			Target = player.Character
		end
	end
	
end

local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {script.Parent}

local function checkSight()
	
	local ray = workspace:Raycast(Torso.Position, (Target.Torso.Position - Torso.Position).Unit * 1000, params)
	if ray then
		if ray.Instance.Parent == Target then
			return true
		else
			return false
		end
	else
		return false
	end
	
end

local function findPath()
	path:ComputeAsync(Torso.Position,Target.Torso.Position)
	local waypoints:{PathWaypoint} = path:GetWaypoints()

	if path.Status == Enum.PathStatus.Success then

		for i, waypoint in pairs(waypoints) do
			Human:MoveTo(waypoint.Position)
			local timeOut = Human.MoveToFinished:Wait()
			
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				
				Human:ChangeState(Enum.HumanoidStateType.Jumping)
				
			end
			
			if not timeOut then
				Human:ChangeState(Enum.HumanoidStateType.Jumping)
				--print("finding new path")
				findPath()
				break
			end
			if checkSight() == true then
				repeat
					print("moving directly to target")
					Human:MoveTo(Target.Torso.Position) -- moving directly towards target
					wait(0.1) -- update every 0.1 seconds
					if Target == nil then
						break
					end
				until checkSight() == false or Human.Health < 1 or Target.Humanoid.Health < 1
				break
			end
			if (Torso.Position - waypoints[1].Position).Magnitude > 20 then
				print("target has moved, generating new path")
				findPath()
				break
			end
		end
	elseif path.Status == Enum.PathStatus.NoPath then
		--print("no path")
	end
end
	
local function main()
	counter += 0.1
	if counter >= 5 then
		getTarget()
	end

	if Target then
		Human.WalkSpeed = 24
		findPath()
		--print("fire")
	else
		--print("no target")
	end
end

while wait(0.1) do
	if Human.Health < 1 then
		break
	end
	main()
end

I am thinking that I could have the destination be in front of the player instead of the player itself. Is there a better option?

1 Like