Pathfind delays other scripts

  1. What do you want to achieve? Keep it simple and clear!

-I want to add a pathfind for my soldier bot

  1. What is the issue? Include screenshots / videos if possible!

-So after I added pathfind to my bot I tested it out, and to my surprise it’s broken. You see if the bot detects a humanoidrootpart it will shoot the target instantly, but after I added pathfind it tends to pause the bot for a moment before shooting. And this is a huge problems because the distance from the bot to the target also effects the delay for some reason. For example I put the bot in front of a target it will shoots instantly, but if I put it let’s say 100 studs away it could take 3-5 seconds for it to shoot.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I have tried multiple solutions weather it be writing a new code to try and replace the old one (which is somehow worse), browse on forums for pathfind fixes and make a separate script.

This is the script I separated from the main code

local Mod = require(script.Parent.Config)
local detectdist = Mod.detectdist
local distancegap = Mod.distancegap
local PFS = game:GetService("PathfindingService")
local char = script.Parent
local MHumanoidrootpart = char:WaitForChild("HumanoidRootPart")
local MHumanoid = char:WaitForChild("Humanoid")
local origin = MHumanoidrootpart.Position
local RS = game:GetService("RunService")

local function findNearestHMRP(ddist)
	local closestHrp = nil
	local pathtoHrp = nil
	for i, v in pairs(workspace.Test:GetDescendants()) do
		local hrp = v:FindFirstChild("HumanoidRootPart")
		if hrp then
			local tmpDis = (hrp.Position - origin).Magnitude
			local hum = v:FindFirstChild("Humanoid")
			if tmpDis < ddist and hum and hum.Health > 0 then
				ddist = tmpDis
				pathtoHrp = hrp
			end
		end
	end
	return pathtoHrp
end

local function pathfind(pathtoHrp)
	if pathtoHrp then
		local path = PFS:CreatePath()
		path:ComputeAsync(MHumanoidrootpart.Position, pathtoHrp.Position)
		local waypoints = path:GetWaypoints()


		for i, waypoint in pairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				MHumanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			end

			if (pathtoHrp.Position - MHumanoidrootpart.Position).Magnitude <= distancegap then
				MHumanoid:MoveTo(MHumanoidrootpart.Position)
				MHumanoid.MoveToFinished:Wait()
			else
				MHumanoid:MoveTo(waypoint.Position)
				MHumanoid.MoveToFinished:Wait()
			end
		end
	end
end

while RS.Heartbeat:Wait() do
	if MHumanoid.Health < 1 then
		break
	end

	local pathtoHrp = findNearestHMRP(detectdist)

	if pathtoHrp and (MHumanoidrootpart.Position - pathtoHrp.Position).Magnitude >= distancegap then
		pathfind(pathtoHrp)
	end
	--distancegap
	--detectdist
end

and if anyone wonder what bot I’m trying to add pathfinding too, it’s a bot from one of SimTek Game Development’s tutorial (specifically this one: Create Non-Playing Characters That Can Target And Kill Enemies In Roblox - YouTube)

1 Like

Your function pathfind(pathtoHrp) is stalling the while loop since the the function is pausing the thread with MHumanoid.MoveToFinished:Wait()
image

You would have to run your pathfinder function on a separate thread and deal with script timing issues/race conditions if you want the AI to be doing other things on top of just moving along a path.

local pathtoHrp
task.defer(function()
    while RS.Heartbeat:Wait() do
        if pathtoHrp and (MHumanoidrootpart.Position - pathtoHrp.Position).Magnitude >= distancegap then
		    pathfind(pathtoHrp)
	    end
    end
end)

while RS.Heartbeat:Wait() do
	if MHumanoid.Health < 1 then
		break
	end

	pathtoHrp = findNearestHMRP(detectdist)

	--distancegap
	--detectdist
end
1 Like

I have tried it, but the problem is still there. Maybe it’s a problem with the main code itself? (I have 2 scripts, 1 for pathfinding and 1 for shooting)

Here it is

--A hodgepodge of scripts put together, lel.

--Variables--

local char = script.Parent
local MHumanoidrootpart = char:WaitForChild("HumanoidRootPart")
local MHumanoid = char:WaitForChild("Humanoid")
local origin = MHumanoidrootpart.Position
local params = RaycastParams.new()
local ATT = char.Gun.Hole.Att
local rnd = Random.new()
local fireanim = script.Fire
local reloadanim = script.Reload
local idleanim = script.Idle
local firinganim = MHumanoid:LoadAnimation(fireanim)
local reloadinganim = MHumanoid:LoadAnimation(reloadanim)
local idleanimation = MHumanoid:LoadAnimation(idleanim)
local inmeleemode = false
local PFS = game:GetService("PathfindingService")
local gunshot = char.Gun.Hole.Sound
local ReloadSnd = char.Gun.Hole.Reload
local loopcnt = 0
local Mod = require(script.Parent.Config)
local distance = Mod.distance
local firerate = Mod.firerate
local mag = Mod.mag
local ammoinmag = Mod.ammoinmag
local reloadtime = Mod.reloadtime
local accuraccy = Mod.accuraccy
local DMG = Mod.DMG
local Firemode = Mod.Firemode
local CQCAction = Mod.CQCAction
local engageCQCdistance = Mod.engageCQCdistance
local keepdistance = Mod.keepdistance
local CQCFiremode = Mod.CQCFiremode
local bursts = Mod.bursts
local burstswaittime = Mod.burstswaittime
local ROF = 1.7/firerate
local burstshot = 0
local RS = game:GetService("RunService")

--Engineering--

MHumanoid:LoadAnimation(idleanim)
MHumanoid:LoadAnimation(fireanim)
MHumanoid:LoadAnimation(reloadanim)

idleanimation:Play()

for i,v in pairs(script.Parent:GetDescendants()) do
	if v:IsA("Part") or v:IsA("MeshPart") then
		v:SetNetworkOwner(nil)
	end
end

local function fireanimation()
	firinganim:Play()
	ATT.FlashFX.Enabled = true
	ATT.Muzzle:Emit(10)
	ATT.Muzzle2:Emit(10)
	ATT.Muzzle3:Emit(10)
	ATT.Muzzle4:Emit(10)
	ATT.OverHeat:Emit(10)
	ATT.Smoke:Emit(10)
	wait()
	ATT.FlashFX.Enabled = false
end

local function fire(eHum)
	gunshot:Play()
	ammoinmag = ammoinmag - 1
	local hitchance = math.random(0,100)
	if hitchance <= accuraccy then
		eHum:TakeDamage(DMG)
	end
	fireanimation()
end

local function findNearestHMRP(dist)
	local closestHrp = nil
	local pathtoHrp = nil
	for i, v in pairs(workspace.Test:GetDescendants()) do
		local hrp = v:FindFirstChild("HumanoidRootPart")
		if hrp then
			local tmpDis = (hrp.Position - origin).Magnitude
			local hum = v:FindFirstChild("Humanoid")
			if tmpDis < dist and hum and hum.Health > 0 then
				dist = tmpDis
				closestHrp = hrp
			end
		end
	end
	return closestHrp
end

local function reload()
	ReloadSnd:Play()
	reloadinganim:Play()
	wait(reloadtime)
	ammoinmag = mag
end

local function target(eHrp)
	if ammoinmag >= 0 then
		local stop = (eHrp.Position-origin).Unit * distance
		params.FilterDescendantsInstances = {char}
		params.FilterType = Enum.RaycastFilterType.Blacklist
		local result =  workspace:Raycast(origin, stop, params)
		if result and result.Instance.Parent and result.Instance.Parent:FindFirstChild("Humanoid") then
			MHumanoidrootpart.CFrame = CFrame.new(
				MHumanoidrootpart.Position, 
				Vector3.new(result.Position.X, MHumanoidrootpart.Position.Y, result.Position.Z)
			)
			if Firemode == 1 then
				fire(eHrp.Parent.Humanoid)
			elseif Firemode == 2 then
				repeat
					if eHrp and eHrp.Parent and eHrp.Parent.Humanoid then
						fire(eHrp.Parent.Humanoid)
						burstshot = burstshot + 1
						wait(ROF*4)
					else
						break
					end
				until burstshot == bursts
				wait(burstswaittime)
				burstshot = 0
			end
		end
	else
		reload()
	end
end

local function panictargeting(eHrp)
	if ammoinmag >= 0 then
		local stop = (eHrp.Position-origin).Unit * distance
		params.FilterDescendantsInstances = {char}
		params.FilterType = Enum.RaycastFilterType.Blacklist
		local result =  workspace:Raycast(origin, stop, params)
		if result and result.Instance.Parent and result.Instance.Parent:FindFirstChild("Humanoid") then
			MHumanoidrootpart.CFrame = CFrame.new(
				MHumanoidrootpart.Position, 
				Vector3.new(result.Position.X, MHumanoidrootpart.Position.Y, result.Position.Z)
			)
			if CQCFiremode == 1 then
				fire(eHrp.Parent.Humanoid)
			elseif CQCFiremode == 2 then
				repeat
					if eHrp.Parent.Humanoid then
						fire(eHrp.Parent.Humanoid)
						burstshot = burstshot + 1
						wait(ROF*4)
					end
				until burstshot == bursts
				wait(burstswaittime)
				burstshot = 0
			end
			if Firemode == 1 and CQCFiremode == true then
				Firemode = 2
			elseif  Firemode == 2 and CQCFiremode == true then
				Firemode = 1
			end
		end
	else
		reload()
	end
end

while RS.Heartbeat:Wait() do
	if MHumanoid.Health < 1 then
		break
	end
	
	local closestHrp = findNearestHMRP(distance)
	
	if closestHrp then
		local dis = (MHumanoidrootpart.Position - closestHrp.Position).Magnitude
		if closestHrp then
			if dis <= engageCQCdistance then
				if CQCAction == 1 then
					print("Engaging CQC")
				elseif CQCAction == 2 then
					panictargeting(closestHrp)
				else
					target(closestHrp)
				end
			else
				target(closestHrp)
			end
		end
	end
end

I tried to combine them into one and the problem is still there.

Have you tried using co-routines? coroutine | Roblox Creator Documentation

1 Like

No I haven’t, tried it yet. Ill try look into it, I’ll mark this as solution if it works.

Alright so I tried it with other pathfinding scripts and they work just fine, idk why mine stalls the shooting script.

Ok so, I found out that I wasn’t updating my origin of the raycast and that it’s not the pathfinding’s fault. oops. Thx everyone who reply anyway, I appreciate it :slight_smile:

2 Likes