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

Making my own Pathfinding

Sometime there're error while I'm using Pathfinding that i take it from this site: http://lessons.lualearners.org/lesson?id=77

Here's a script i make it for Zombie

local larm = script.Parent:FindFirstChild("Left Arm")
local rarm = script.Parent:FindFirstChild("Right Arm")
local waitTimer = 0
nodesTraced = {} 
nodes = Workspace:FindFirstChild("Nodes")

function mapNodes()
	if nodes == nil then 
		message = Instance.new("Message", Workspace) 
		message.Text = "The model \"Nodes\" does not exist in Workspace. This should contain all your nodes." 
	else 
		local nodesChildren = nodes:getChildren()
		for _, node in pairs(nodesChildren) do
			for _, targetNode in pairs(nodesChildren) do 
				--wait()
				if targetNode ~= node then 
					local ray = castRay(node.Position, targetNode.Position)
					local hit,_ = Workspace:FindPartOnRay(ray, node) 
				
					if hit == targetNode then
						if nodesTraced[node] == nil then
							nodesTraced[node] = {}
						end
						nodesTraced[node][targetNode] = true 
					end							
				end
			end
		end		
	end
end

function castRay(start, target) 
	local ray = Ray.new(start, (target - start).unit*300) 
	return ray 
end 

function pathFind(startNode, endNode) 
	
	local openList = {} 
	local closedList = {} 
	
	openList[startNode] = {startNode, 0, 0} 
	
	local endFound = false
	local currentNode = nil 
	
	while endFound == false do 
		--wait() 
				
		local lowestF = math.huge 
		local openListNotEmptyCheck = 0 

		for key, value in pairs(openList) do 
			--wait()
			openListNotEmptyCheck = openListNotEmptyCheck+1 

			if value[2] < lowestF then 
				lowestF = value[2] 
				currentNode = key 
			end
		end
		
		if openListNotEmptyCheck == 0 then 

			return false 
		end
		
		closedList[currentNode] = {openList[currentNode][1],openList[currentNode][3]} 
		openList[currentNode] = nil 
		
		if currentNode == endNode then 
			endFound = true 
		end
		
		for key, value in pairs(nodesTraced[currentNode]) do --Here's a error that i can't fix.
			--wait() 
			if closedList[key] == nil then 
				local g = closedList[currentNode][2] + (key.Position - currentNode.Position).magnitude 
				local h = (key.Position - endNode.Position).magnitude 
				local f = g + h
				if openList[key] and openList[key][3] > g then 
					openList[key] = {currentNode, f, g}	 
				elseif openList[key] == nil then 
					openList[key] = {currentNode, f, g}	
				end
			end

		end		
		
	end
	local backPath = {} 
	backPathDone = false 
	
	table.insert(backPath, endNode) 
	
	while backPathDone == false do 
		wait() 
		table.insert(backPath, closedList[currentNode][1]) 
		currentNode = closedList[currentNode][1] 
		if currentNode == startNode then 
			backPathDone = true 
		end				
		
	end
	
	local path = {} 
	
	for i = #backPath, 1, -1 do 
		table.insert(path, backPath[i]) 
	end
	return path 
end

function findNearestTorso(pos)
	local list = game.Workspace:children()
	local torso = nil
	local dist = 1000
	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) and (temp2.Name ~= "Floating Fortress") then
			temp = temp2:findFirstChild("Torso")
			human = temp2:findFirstChild("Humanoid")
			if (temp ~= nil) and (human ~= nil) and (human.Health > 0) and (temp2.Name ~= "Zombie") and (temp2.Torso.Position.Y < 20) then
				if (temp.Position - pos).magnitude < dist then
					torso = temp
					script.Parent.Target.Value = temp
					dist = (temp.Position - pos).magnitude

					if human.Health >= 1 then 
					script.Parent.Range.Value = true 
					else 
					script.Parent.Range.Value = false 
					end 
				end
			end
			if dist < 50 then 
				script.Parent.Attack.Value = true 
			else 
				script.Parent.Attack.Value = false 
			end 
		end
	end
	return torso
end

function Hit(hit)
	local human = hit.Parent:FindFirstChild("Humanoid")
	if human ~= nil and waitTimer <= 0 and hit.Parent.Name ~= "Zombie" then
		human:TakeDamage(20)
		script.Parent.Humanoid.Health = script.Parent.Humanoid.Health + 5
		script.Parent.Head.Bite:play()
		waitTimer = 2
	end
end

function Sit()
	if script.Parent.Humanoid.Sit == true then 
		script.Parent.Humanoid.Jump = true 
		print("Anti Seat Putter!!!")
	end 
end 

script.Parent.Humanoid.Changed:connect(Sit)
for _, Child in pairs(script.Parent:GetChildren()) do
	if Child:IsA("Part") then
		Child.Touched:connect(Hit)
	end
end

while true do
	wait(0.1)
	mapNodes()
	--[[while script.Parent.HoldAttack.Value == true do
		script.Parent.Range.Value = false 
		script.Parent.Attack.Value = false 
		wait()
	end
	waitTimer = waitTimer - 1
	local target = findNearestTorso(script.Parent.Torso.Position)
	if target ~= nil then
		rx = math.random(-15,15)/10
		ry = math.random(0,0)
		rz = math.random(-15,15)/10
		script.Parent.Humanoid:MoveTo(target.Position+Vector3.new(rx,ry,rz), target)
	else 
		script.Parent.Range.Value = false 
		script.Parent.Attack.Value = false 
	end]]
	pathFind(nodes.Start, nodes.End)
end

Error I've found using output:

20:43:44.578 - Workspace.Zombie.ChaseScript:75: bad argument #1 to 'pairs' (table expected, got nil) 20:43:44.609 - Script 'Workspace.Zombie.ChaseScript', Line 75 - global pathFind 20:43:44.609 - Script 'Workspace.Zombie.ChaseScript', Line 192 20:43:44.609 - stack end

Please tell me a way to fix this. Thanks

2 answers

If its a model your trying to get the children of use the following:

for _, v in pairs(Model:GetChildren()) do
end

Your error expects a table, not a object, for a table use the following:

bob = {"ASDF","QWERTY"}
for _, v in pairs(bob) do
end

Now i know how to make success Pathfinding. But not success using Terrain as Obstacle

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