So I worked for 2 nights making this pathfinding script. It actually worked after I finished it last night, just needed a few bugs worked out. Today, I opened up ROBLOX Studio and there was an update. After updating, I opened my place and clicked "Play" while in "Edit" mode to make sure ROBLOX didn't break anything. Apparently they did.
Script:
wait(10) -- To allow time for Pathing script to name all nodes and for player to load
--Variable Declarations
Nodes = Workspace:findFirstChild("Pathing")
NumNodes = 1
NodeList = {}
NodeCon = {}
z = 1
NodePos = {}
Node = Nodes:findFirstChild("Node"..NumNodes)
Dist = 100
DiagDist = 200
--Functions
function FindNear(Node,Closed,Num)
x = 1
ReturnList = {}
for y = 1, NumNodes do
if DistTo(NodeList[y],Node) == Dist or DistTo(NodeList[y],Node) == DiagDist then
Open = true
for z=1,Num do
if NodeList[y] == Closed[z] then
Open = false
end
end
if Open == true then
ReturnList[x] = NodeList[y]
x = x + 1
end
end
end
return ReturnList
end
function NumberNear(Node,Closed,Num)
x = 0
for y = 1, NumNodes do
if DistTo(NodeList[y],Node) == Dist or DistTo(NodeList[y],Node) == DiagDist then
Open = true
for z=1,Num do
if NodeList[y] == Closed[z] then
Open = false
end
end
if Open == true then
x = x + 1
end
end
end
return x
end
function FindMove(Start,End)
local Current = Start
local ClosedSet = {}
local NumClosed = 0
local Adjacent = {}
local PossNext = {}
local CurrentPath = {}
local PathNum = 1
local NumPosNex = 0
local NexDis = 1000
local Runs = 0
local Next = nil
while Current ~= End and Runs <= NumNodes do
Runs = Runs + 1
if CurrentPath[PathNum] == nil then
CurrentPath[PathNum] = Current
PathNum = PathNum + 1
end
Adjacent = FindNear(Current,ClosedSet,NumClosed)
for x = 1,NumberNear(Current,ClosedSet,NumClosed) do
if Adjacent[x] ~= nil then
if DistTo(Adjacent[x],End) < DistTo(Current,End) then
NumPosNex = NumPosNex + 1
PossNext[NumPosNex] = Adjacent[x]
end
end
end
for x = 1,NumPosNex do
if PossNext[x] ~= End then
if DistTo(PossNext[x],End) < NexDis then
NexDis = DistTo(PossNext[x],End)
Next = PossNext[x]
end
else
Next = End
NexDis = -1000
x = 1000
end
end
for x = NumPosNex,1,-1 do
PossNext[x] = nil
end
NumPosNex = 0
if Next ~= nil then
CurrentPath[PathNum] = Next
PathNum = PathNum + 1
Current = Next
NumClosed = NumClosed + 1
ClosedSet[NumClosed] = Next
else
for x=PathNum,1,-1 do
CurrentPath[x] = nil
end
PathNum = 1
Current = Start
end
Next = nil
NexDis = 1000
end
if CurrentPath[2] ~= nil then
return CurrentPath
else
return nil
end
end
function DistTo(Start,End)
Ans = math.sqrt(math.pow(math.abs(Start.Position.x - End.Position.x),2) + math.pow(math.abs(Start.Position.z - End.Position.z),2))
return Ans
end
function FindClosest(Target)
closeDist = 100
close = nil
for x=1,NumNodes do
if DistTo(NodeList[x],Target) < closeDist then
close = NodeList[x]
closeDist = DistTo(NodeList[x],Target)
end
end
return close
end
--I do not take credit for findNearestTorso script.
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) then
temp = temp2:findFirstChild("Right Arm")
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
--Main
while Node ~= nil do
NodeList[NumNodes] = Node
NumNodes = NumNodes + 1
Node = Nodes:findFirstChild("Node"..NumNodes)
end
NumNodes = NumNodes - 1
for x=1,NumNodes-1 do
for y=x+1,NumNodes do
D = DistTo(NodeList[x],NodeList[y])
if D < Dist then
Dist = D
end
end
end
DiagDist = math.sqrt(math.pow(Dist,2) + math.pow(Dist,2))
while true do
Target = findNearestTorso(script.Parent.Torso.Position)
TargetMoved = false
CloseNode = FindClosest(Target)
PathNum = 1
while CloseNode ~= nil and TargetMoved == false do
wait(.1)
Path = FindMove(FindClosest(script.Parent.Torso),CloseNode)
if Path ~= nil then
while TargetMoved == false and CloseNode ~= nil do
while DistTo(script.Parent.Torso,Path[PathNum]) > 7 do
wait(.1)
script.Parent.Humanoid:MoveTo(Path[PathNum].Position, Path[PathNum])
if FindClosest(Target) ~= CloseNode then
TargetMoved = true
end
end
if Path[PathNum] == CloseNode then
CloseNode = nil
else
PathNum = PathNum + 1
end
end
else
print("No Path")
end
end
Closest = FindClosest(Target)
while Target ~= nil and TargetMoved == false do
wait(.1)
script.Parent.Humanoid:MoveTo(Target.Position, Target)
if Closest ~= FindClosest(Target) and DistTo(Target,script.Parent.Torso) < 20 then
TargetMoved = true
end
end
end
Output:
12:37:38.299 - Workspace.Pathing.Pathfinder.Script:115: attempt to index local 'End' (a nil value)
12:37:38.299 - Stack Begin
12:37:38.300 - Script 'Workspace.Pathing.Pathfinder.Script', Line 115 - global DistTo
12:37:38.300 - Script 'Workspace.Pathing.Pathfinder.Script', Line 122 - global FindClosest
12:37:38.301 - Script 'Workspace.Pathing.Pathfinder.Script', Line 172
12:37:38.301 - Stack End
Apparently on line 115, "End" is a nil value, but I don't see WHY it's a nil value.
On a side note: There are 120 Nodes on the map.
