Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Pathfinding Script Randomly Broke?

Asked by
OniiCh_n 410 Moderation Voter
10 years ago

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.

Answer this question