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

Making my own Pathfinding

Asked by 9 years ago

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

Log in to vote
2
Answered by 9 years ago

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

Ad
Log in to vote
0
Answered by 9 years ago

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

Answer this question