Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Why won't my path finding NPC walk to me?

local mode = "move"
local dist = 50
local hrp = workspace:WaitForChild("humanoid"):WaitForChild("UpperTorso")
while wait() do
	for i ,v  in pairs(workspace:GetChildren{}) do
		local Target = nil
		local humanoid = v:FindFirstChild("Humanoid")
			if humanoid and v.Parent ~= "humanoid" and v.Name ~= "humanoid" then
				print(v.Name)
				if (workspace.humanoid.UpperTorso.Position - v:WaitForChild("UpperTorso").Position).magnitude < 500 then
					Target = v.UpperTorso.Position
					path = game:GetService("PathfindingService"):ComputeRawPathAsync(v.UpperTorso.Position, Target, 600)
					points = path:GetPointCoordinates()
					game.Workspace.Points:ClearAllChildren()
					if mode == "move" then
						print(#points)
						for Num = 1, #points do
							local hum = workspace.humanoid
							hum.Humanoid:MoveTo(points[Num])
							repeat
							distance =(points[Num] - hum.LowerTorso.Position).magnitude
							wait()
							until distance < 3
						end
					end
				end
			end
		end
	end

'print(#points)' prints 0 when it should be > 0 but i don't know what's wrong with it.

3 comments

0

It looks like you are setting the path to go to itself. In line 11, Target is set to the player's upper torso. in line 12, it tries to compute a path from the UpperTorso to target, which is set to UpperTorso.

0

Thanks you fixed my issue. However, the NPC is really laggy and the script runs many times a second. I tried increasing the time in the wait() but that didn't work. Do you have any fix for this?

0

i would reccomend making the function run only when someone does something. So like, if you move, it will run the function or something. When you use while wait() do it is running so often it lags

1 answer

you can do this and put a value called Target

debugMode = false
targetNPCs = false

--

h = script.Parent.Parent:WaitForChild("Humanoid")
pathService = game:GetService("PathfindingService")
targetV = script.Parent:WaitForChild("Target")

function closestTargetAndPath()
	local humanoids = {}
	if targetNPCs then
		local function recurse(o)
			for _,obj in pairs(o:GetChildren()) do
				if obj:IsA("Model") then
					if obj:findFirstChild("Humanoid") and obj:findFirstChild("Torso") and obj.Humanoid ~= h and obj.Humanoid.Health > 0 and not obj:findFirstChild("ForceField") then
						table.insert(humanoids,obj.Humanoid)
					end
				end
				recurse(obj)
			end
		end
		recurse(workspace)
	else
		for _,v in pairs(game.Players:GetPlayers()) do
			if v.Character and v.Character:findFirstChild("HumanoidRootPart") and v.Character:findFirstChild("Humanoid") and v.Character.Humanoid.Health > 0 and not v:findFirstChild("ForceField") then
				table.insert(humanoids,v.Character.Humanoid)
			end
		end
	end
	local closest,path,dist
	for _,humanoid in pairs(humanoids) do
		local myPath = pathService:ComputeRawPathAsync(h.Torso.Position,humanoid.Torso.Position,500)
		if myPath.Status ~= Enum.PathStatus.FailFinishNotEmpty then
			-- Now that we have a successful path, we need to figure out how far we need to actually travel to reach this point.
			local myDist = 0
			local previous = h.Torso.Position
			for _,point in pairs(myPath:GetPointCoordinates()) do
				myDist = myDist + (point-previous).magnitude
				previous = point
			end
			if not dist or myDist < dist then -- if true, this is the closest path so far.
				closest = humanoid
				path = myPath
				dist = myDist
			end
		end
	end
	return closest,path
end

function goToPos(loc)
	h:MoveTo(loc)
	local distance = (loc-h.Torso.Position).magnitude
	local start = tick()
	while distance > 4 do
		if tick()-start > distance/h.WalkSpeed then -- Something may have gone wrong. Just break.
			break
		end
		distance = (loc-h.Torso.Position).magnitude
		wait()
	end
end

while wait() do
	local target,path = closestTargetAndPath()
	local didBreak = false
	local targetStart
	if target and h.Torso then
		targetV.Value = target
		targetStart = target.Torso.Position
		roaming = false
		local previous = h.Torso.Position
		local points = path:GetPointCoordinates()
		local s = #points > 1 and 2 or 1
		for i = s,#points do
			local point = points[i]
			if didBreak then 
				break
			end
			if target and target.Torso and target.Health > 0 then
				if (target.Torso.Position-targetStart).magnitude < 1.5 then
					local pos = previous:lerp(point,.5)
					local moveDir = ((pos - h.Torso.Position).unit * 2)
					goToPos(previous:lerp(point,.5))
					previous = point
				end
			else
				didBreak = true
				break
			end
		end
	else
		targetV.Value = nil
	end
	if not didBreak and targetStart then
		goToPos(targetStart)
	end
end

2 comments

0

I got an error line 94: Value is not a valid member of Part

0

you have to insert a vaule

This discussion is preserved as it was. New answers, comments, and votes are closed.