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

Ai following one player please help?

Asked by 5 years ago

I´m creating a horror game, i created a mian script who works for all ai on a folder but i have a problem it follows only one player and ignore the others players

local Distance = 40

local Damage = 100  

local scaryimg = game.ReplicatedStorage:WaitForChild("ScaryPlayer")

local candamage = true

local Wander = true
local WanderX, WanderZ = 10, 10

function Added(Monsters)
    spawn(function()

    function getHumanoid(model)
        for _, v in pairs(model:GetChildren()) do
            if v:IsA'Humanoid' --[[v:FindFirstChild("Humanoid")]] then
                return v
            end
        end 
    end

    local zombie = Monsters

    local human = getHumanoid(zombie)
    local hroot = zombie:FindFirstChild("HumanoidRootPart")
    local zspeed = hroot.Velocity.magnitude


    local pfs = game:GetService("PathfindingService")

    function GetPlayerNames()
        local players = game:GetService('Players'):GetChildren()
        local name = nil
        for _, v in pairs(players) do
            if v:IsA'Player' then
                name = tostring(v.Name)
            end
        end
        return name
    end
    function GetPlayersBodyParts(t)
        local torso = t
        if torso then
            local figure = torso.Parent
            if figure then
            for _, v in pairs(figure:GetChildren()) do
                if v:IsA'Part' then
                    return v.Name
                end
                end
            end
        else
            return "HumanoidRootPart"
        end
    end

    function GetTorso(part)
        local chars = game.Workspace:GetChildren()
        local torso = nil
        for _, v in pairs(chars) do
            if v:IsA'Model' and v ~= script.Parent and v.Name == GetPlayerNames() then
                local charRoot = v:FindFirstChild'HumanoidRootPart'
                if (charRoot.Position - part).magnitude < Distance then
                    torso = charRoot
                end
            end
        end
        return torso
    end

    local path
    local waypoint
    local oldpoints
    local isWandering = 0

    if Wander then
        spawn(function()
            while isWandering == 0 do
                isWandering = 1
                local desgx, desgz = hroot.Position.x + math.random(-WanderX, WanderX), hroot.Position.z + math.random(-WanderZ, WanderZ)
                human:MoveTo( Vector3.new(desgx, 0, desgz) )
                wait(math.random(4, 6))
                isWandering = 0
            end
        end)
    end

    while wait() do
        local enemytorso = GetTorso(hroot.Position) 
        if enemytorso ~= nil then -- if player detected
            isWandering = 1
            local function checkw(t)
                local ci = 3
                if ci > #t then
                    ci = 3
                end
                if t[ci] == nil and ci < #t then
                    repeat
                        ci = ci + 1
                        wait()
                    until t[ci] ~= nil
                    return Vector3.new(1, 0, 0) + t[ci]
                else
                    ci = 3
                    return t[ci]
                end
            end

            path = pfs:FindPathAsync(hroot.Position, enemytorso.Position)
            waypoint = path:GetWaypoints()
            oldpoints = waypoint
            local connection;

            local direct = Vector3.FromNormalId(Enum.NormalId.Front)
            local ncf = hroot.CFrame * CFrame.new(direct)
            direct = ncf.p.unit
            local rootr = Ray.new(hroot.Position, direct)
            local phit, ppos = game.Workspace:FindPartOnRay(rootr, hroot)

            if path and waypoint or checkw(waypoint) then
                if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then
                    human:MoveTo( checkw(waypoint).Position )
                    human.Jump = false
                end

                if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Jump then
                    human.Jump = true
                    connection = human.Changed:connect(function()
                        human.Jump = true
                    end)
                    human:MoveTo( checkw(waypoint).Position )
                else
                    human.Jump = false
                end

                hroot.Touched:connect(function(p)
                    local bodypartnames = GetPlayersBodyParts(enemytorso)
                    if p:IsA'Part' and not p.Name == bodypartnames and phit and phit.Name ~= bodypartnames and phit:IsA'Part' and rootr:Distance(phit.Position) < 5 then
                        connection = human.Changed:connect(function()
                            human.Jump = true
                        end)
                    else
                        human.Jump = false
                    end
                end)

                if connection then
                    connection:Disconnect()
                end

            else
                for i = 3, #oldpoints do
                    human:MoveTo( oldpoints[i].Position )   
                end
            end
        elseif enemytorso == nil and canWander then -- if player not detected
            isWandering = 0
            path = nil
            waypoint = nil
            human.MoveToFinished:Wait()
        end
    end
    end)
end

workspace.AiEnemys.ChildAdded:connect(Added)

for _,Monsters in pairs(workspace.AiEnemys:GetChildren())do
    wait(0.1)
    Added(Monsters) --CALL THE CODE WHEN PLAYER ENTER
end

Help me please i need this urgently Thanks

2 answers

Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

You issue is likely here:

function GetTorso(part)
            local chars = game.Workspace:GetChildren()
            local torso = nil
            for _, v in pairs(chars) do
                if v:IsA'Model' and v ~= script.Parent and v.Name == GetPlayerNames() then
                    local charRoot = v:FindFirstChild'HumanoidRootPart'
                    if (charRoot.Position - part).magnitude < Distance then
                        torso = charRoot
                    end
                end
            end
            return torso
        end

Specifically here:

  local charRoot = v:FindFirstChild'HumanoidRootPart'
                if (charRoot.Position - part).magnitude < Distance then
                    torso = charRoot
                end

You are not comparing the player distances, you will always get the last player in the Chars table. Assuming you are going for the closest player, you need to compare the current v value with the current torso's distance to the monster and set torso equal to which one is closer.

0
ok thanks imagYTOP 19 — 5y
Ad
Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

i Tried make something similar like you said me but i don´t works:

--New Code

function GetTorso(pos)
        local char = game.Workspace:children()
        local torso = nil
        local Id = nil
        local human = nil
        local Ad = nil
        for ea = 1, #char do
            Ad = char[ea]
            if (Ad.className == "Model") and (Ad ~= script.Parent)  then
                Id = Ad:findFirstChild("Torso")
                local charRoot = Ad:findFirstChild("Humanoid")
                if (Id ~= nil) and (charRoot ~= nil)  then
                    if (Id.Position - pos).magnitude < SearchDistance then
                        torso = Id
                    end
                end
            end
        end
        return torso
    end

please help me with this thanks

sorry im so noob with the pathfinder

Answer this question