How would I make a efficient chasing monster

So let me start off with I have a good amount of knowledge for PathFindingService
But never used it for an enemy that chases a player that moves constantly so I need some help because my enemy ai is stuttering here is a visual to see what is going on


and here is my script

--Variables
local PathFindingService = game:GetService("PathfindingService")
local Character = script.Parent
local Hitbox = Character:WaitForChild("Hitbox")
local Humanoid = Character:WaitForChild("Humanoid")
local Main_HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local PathParams = {AgentHeight = 4.5,AgentRadius = 2.5,AgentCanJump = true}
local Debounce_Paths = {}
--Empty Variables
local ChasingPlayer = nil
--Functions

function HowManyCharactersAreAlive()
	local HowManyAlive = 0
	for i,Player in pairs(game.Players:GetPlayers()) do
		local Character = Player.Character
		if Character then
			local Humanoid = Character:FindFirstChild("Humanoid")
			if Humanoid then
				if Humanoid.Health > 0 then
					HowManyAlive = HowManyAlive + 1
				end
			end
		end

	end
	return HowManyAlive
end

function NearestPlayer()
	local NearestValue = 0
	local NearestPlayer
	for i,Player in pairs(game.Players:GetPlayers()) do
		local Character = Player.Character
		local Humanoid = Character:WaitForChild("Humanoid")
		local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
		local Distance = (Main_HumanoidRootPart.Position - HumanoidRootPart.Position).magnitude
		print(Distance)
		if Distance > NearestValue and Humanoid.Health > 0 then
			NearestValue = Distance
			NearestPlayer = Player
		end
	end
	if NearestPlayer ~= nil then
		print(NearestPlayer.Name)
		return NearestPlayer
	else
		return nil
	end
end
--Code
Hitbox.Touched:connect(function(Hit)
	local Player = game.Players:FindFirstChild(Hit.Parent.Name)
	if Player then
		local Character = Player.Character
		local Humanoid = Character:WaitForChild("Humanoid")
		Humanoid:TakeDamage(100)
	end
end)

while true do	
	if HowManyCharactersAreAlive() > 0 then
		if ChasingPlayer == nil then
			local NearestPlayer = NearestPlayer()
			if NearestPlayer ~= nil then
				local Character = NearestPlayer.Character
				local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
				local path = PathFindingService:CreatePath(PathParams)
				path:ComputeAsync(Main_HumanoidRootPart.Position,HumanoidRootPart.Position)
				local WayPoints = path:GetWaypoints()
				print(path.Status)
				for i,Waypoint in pairs(WayPoints) do
					if Waypoint.Action == Enum.PathWaypointAction.Jump then
						Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
					end
					print(Waypoint)
					local Part = Instance.new("Part",workspace)
					game:GetService("Debris"):AddItem(Part,2)
					Part.CanCollide = false
					Part.Transparency = .5
					Part.Anchored = true
					Part.Position = Waypoint.Position
					if Waypoint.Action == Enum.PathWaypointAction.Jump then
						Humanoid.Jump = true
					end
					Humanoid:MoveTo(Waypoint.Position)

				end

			end
		end
	else
		wait(2)
	end

end

Any help will be appreciated

6 Likes

Very late response, I know. But u can do this by making the monster path find to 10 studs infront of the player if the monster’s humanoid walk speed is faster than the player’s. It should then get to you and even touch you.

2 Likes

You can try this, But this is not mine.

local larm = script.Parent:FindFirstChild("HumanoidRootPart")
local rarm = script.Parent:FindFirstChild("HumanoidRootPart")

function findNearestTorso(pos)
	local list = game.Workspace:children()
	local torso = nil
	local dist = 10000
	local temp = nil
	local human = nil
	local temp2 = nil
	for x = 1, #list do
		temp2 = list[x]
		if (temp2.className == "Model") and (temp2 ~= script.Parent) then
			temp = temp2:findFirstChild("HumanoidRootPart")
			human = temp2:findFirstChild("Humanoid")
			if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
				if (temp.Position - pos).magnitude < dist then
					torso = temp
					dist = (temp.Position - pos).magnitude
				end
			end
		end
	end
	return torso
end




while true do
	wait(1)
	local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
	if target ~= nil then
		script.Parent.Zombie:MoveTo(target.Position, target)
	end

end

You can simply place this in a Script (Not LocalScript) inside the Monster Model you got.

Based on what I see in the video, the problem is that the network ownership is constantly being set to the closest player. Now that’s an issue because there’s a delay when the network ownership is set which makes the monster teleport back. So there’s an easy to this.

After getting the HumanoidRootPart you do this:

Main_HumanoidRootPart:SetNetworkOwner(nil) -- Sets the network ownership to the server

And also I would recommend putting Humanoid.MoveToFinished:Wait() after Humanoid:MoveTo()

To add onto that example, Schloss means like this:

Humanoid:MoveTo(pos)
Humanoid.MovedToFinished:Wait()