[SOLVED] Why is sometimes my AI not working? (Simple Path)

You can do other things, like print the distance from the AI to the nearest player. If it prints nil or something unexpected then you know you have to look at how you find the closest player, or maybe your distance calculation.

If it prints a distance and doesn’t move then you’ve traced it to a pathfinding issue.

Also, if you use Pathfinding and the travel distance time is over 8 seconds then the NPC will stop.

Check this link as well: Character Pathfinding

1 Like

This is all great and all… but how the heck can i do this?

Use Path finding service and it will solve your problem(watch youtube)

NEVER EVER DO THIS
NPC.HumanoidRootPart.Anchored = false – this will cause a lot of problems
Instead
NPC.Humanoid.WalkSpeed = 0

Instead of asking a very vague “how the heck can I do this?” tell me how you’ve tried the steps I’ve suggested and what happened. If you don’t know about any of the steps then ask about that exact part of it.

Try making just 1 zombie spawn and see if that one works properly. If it does and you add a 2nd zombie it breaks then you know the script isn’t referencing which zombie to send to which location.

I can see that you’re using other people’s scripts to do this, and don’t really understand what is going on. I’m not a pro scripter, I’m just trying to help you to be able to figure out where to look to find the source of the issue.

You’re already getting the distance in the findClosestPlayer function, so print("distance = ", distance) to see what it is.

The Character Pathfinding links I posted above tells you EXACTLY how to get an NPC to walk from one point to another. If you’d read it through you would know a little bit about Pathfinding. I see that one person clicked the second link, but nobody has clicked the first link.

You’re getting the position of the closest player in your script, so you can make a path from the zombie to the player’s position.

There are also plenty of posts on the forum about making NPCs move to or follow players. You could try using the Search tool up top to try looking for them.

wait, i didn’t knew the roblox pathfinding was that good, WHAAAAAAT?

Oh and also just a question, is this optimized:

local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local path = PathfindingService:CreatePath({
	AgentRadius = 2,
	AgentHeight = 6,
	AgentCanJump = true,
	AgentCanClimb = true,
	Costs = {
		Climb = 4
	}
})

local TEST_DESTINATION = nil

local function findClosestPlayer()
	--pcall(function()
	local closestPlayer, closestDistance = nil, math.huge
	for _, player in ipairs(Players:GetPlayers()) do
		local character = player.Character
		if character and character:WaitForChild("Humanoid") then
			local distance = (character.HumanoidRootPart.Position - script.Parent.PrimaryPart.Position).Magnitude
			if distance < closestDistance then
				closestPlayer = player
				closestDistance = distance
			end
		end
	end
	return closestPlayer
	--end)
end

local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection

local function followPath(destination)
	-- Compute the path
	local success, errorMessage = pcall(function()
		path:ComputeAsync(script.Parent.PrimaryPart.Position, destination)
	end)

	if success and path.Status == Enum.PathStatus.Success then
		-- Get the path waypoints
		waypoints = path:GetWaypoints()

		-- Detect if path becomes blocked
		blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
			-- Check if the obstacle is further down the path
			if blockedWaypointIndex >= nextWaypointIndex then
				-- Stop detecting path blockage until path is re-computed
				blockedConnection:Disconnect()
				-- Call function to re-compute new path
				followPath(destination)
			end
		end)

		-- Detect when movement to next waypoint is complete
		if not reachedConnection then
			reachedConnection = script.Parent.Humanoid.MoveToFinished:Connect(function(reached)
				if reached and nextWaypointIndex < #waypoints then
					-- Increase waypoint index and move to next waypoint
					nextWaypointIndex += 1
					script.Parent.Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
				else
					reachedConnection:Disconnect()
					blockedConnection:Disconnect()
				end
			end)
		end

		-- Initially move to second waypoint (first waypoint is path start; skip it)
		nextWaypointIndex = 2
		script.Parent.Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
	else
		warn("Path not computed!", errorMessage)
	end
end

local ClosestPlayer = findClosestPlayer()
--followPath(TEST_DESTINATION)
if ClosestPlayer then
	while task.wait() do
		TEST_DESTINATION = ClosestPlayer.Character.PrimaryPart.Position
		followPath(TEST_DESTINATION)
	end
end

YOO, I THINK I FINALLY FIXED IT! Here is the new script:

local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local NPC = script.Parent
local AttackAnim = NPC.Humanoid:LoadAnimation(NPC.Animations.Attack)

local DamageEvent = game.ReplicatedStorage.Events.DamageEvent

local RaycastHitbox = require(ReplicatedStorage.Modules.RaycastHitboxV4)

local path = PathfindingService:CreatePath({
	AgentRadius = 3,
	AgentHeight = 6,
	AgentCanJump = true,
	AgentCanClimb = true,
	Costs = {
		Climb = 4
	}
})

local M1DB = false

local TEST_DESTINATION = nil

local function findClosestPlayer()
	--pcall(function()
	local closestPlayer, closestDistance = nil, math.huge
	for _, player in ipairs(Players:GetPlayers()) do
		local character = player.Character
		if character and character:WaitForChild("Humanoid") then
			local distance = (character.HumanoidRootPart.Position - NPC.PrimaryPart.Position).Magnitude
			if distance < closestDistance then
				closestPlayer = player
				closestDistance = distance
			end
		end
	end
	return closestPlayer
	--end)
end

local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection

local function followPath(destination)
	local player = findClosestPlayer()
	local character = player.Character
	local distance = (character.HumanoidRootPart.Position - NPC.PrimaryPart.Position).Magnitude
	-- Compute the path

	if distance < 10 then
		local NewHitbox = RaycastHitbox.new(NPC)
		local Params = RaycastParams.new()
		Params.FilterType = Enum.RaycastFilterType.Exclude
		Params.FilterDescendantsInstances = {NPC}
		NewHitbox.RaycastParams = Params
		AttackAnim:Play()
		NewHitbox.Visualizer = true
		NewHitbox.OnHit:Connect(function(hit, hum)
			if M1DB == false then
				if player:FindFirstChild("Invincible").Value == false then
					M1DB = true
					player:FindFirstChild("Invincible").Value = true
					ReplicatedStorage.Events.DamageEvent:FireClient(player)
				end
			end
		end)
		NewHitbox:HitStart(1)
		task.wait(2)
		M1DB = false
	end
	local success, errorMessage = pcall(function()
		path:ComputeAsync(NPC.PrimaryPart.Position, destination)
	end)

	if success and path.Status == Enum.PathStatus.Success then
		-- Get the path waypoints
		waypoints = path:GetWaypoints()

		-- Detect if path becomes blocked
		blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
			-- Check if the obstacle is further down the path
			if blockedWaypointIndex >= nextWaypointIndex then
				-- Stop detecting path blockage until path is re-computed
				blockedConnection:Disconnect()
				-- Call function to re-compute new path
				followPath(destination)
			end
		end)

		-- Detect when movement to next waypoint is complete
		if not reachedConnection then
			reachedConnection = NPC.Humanoid.MoveToFinished:Connect(function(reached)
				if reached and nextWaypointIndex < #waypoints then
					-- Increase waypoint index and move to next waypoint
					nextWaypointIndex += 1
					NPC.Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
				else
					reachedConnection:Disconnect()
					blockedConnection:Disconnect()
				end
			end)
		end

		-- Initially move to second waypoint (first waypoint is path start; skip it)
		nextWaypointIndex = 2
		NPC.Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
	end
end

DamageEvent.OnServerEvent:Connect(function(Player, Value)
	if Value == "Damage" then
		Player.Character.Humanoid:TakeDamage(10)
	elseif Value == "" or Value == nil then
		Player:FindFirstChild("Invincible").Value = false
	end
end)

local ClosestPlayer = findClosestPlayer()
--followPath(TEST_DESTINATION)
if ClosestPlayer then
	while task.wait() do
		TEST_DESTINATION = ClosestPlayer.Character.PrimaryPart.Position
		followPath(TEST_DESTINATION)
	end
end
1 Like

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