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

I try to fix the npcs so they don't attack eachother, but they still do. Fix?

Asked by 3 years ago

The code is right here:

    local Temp2 = nil
    for x = 1, #List do
        Temp2 = List[x]
        if (Temp2.className == "Model") and (Temp2 ~= script.Parent) then
            Temp = Temp2:findFirstChild("HumanoidRootPart")
            Human = Temp2:findFirstChild("Humanoid")
            local plr = Human.Name
            if players:FindFirstChild(plr) then
            if (Temp ~= nil) and (Human ~= nil) and (Human.Health > 0) then
                if (Temp.Position - Position).magnitude < Distance then
                    Torso = Temp
                    Distance = (Temp.Position - Position).magnitude
                        end
                    end
                end
            end
        return Torso
    end
end




while true do
    local target = findNearestPlayer(script.Parent.HumanoidRootPart.Position)
        if not target.Name == ("Goblin") then --how i try to make them not attack eachother
        if target ~= nil then
            script.Parent.Humanoid:MoveTo(target.Position, target)
        end
    end
end

I do not get any errors.

2 answers

Log in to vote
0
Answered by 3 years ago

Only search through players so that you won't have a chance of finding other goblins.

local function findNearestPlayer(pos)
    local closestRoot
    local closestDist
    for _, player in ipairs(game.Players:GetPlayers()) do -- Iterate over only the players
        local char = player.Character
        local humanoid = char and char:FindFirstChild("Humanoid") -- The "char and" is just in case a player's character is nil
        if humanoid and humanoid.Health > 0 then
            local root = char:FindFirstChild("HumanoidRootPart")
            if root then
                local dist = (root.Position - pos).Magnitude
                if not closestRoot or dist < closestDist then -- if this is the first player we've found or if it's closer than the closest player we've found so far
                    closestRoot = root
                    closestDist = dist
                end
            end
        end
    end
    return closestRoot
end

local root = script.Parent.HumanoidRootPart
local humanoid = script.Parent.Humanoid
while true do
    wait(1) -- Don't forget to pause periodically to prevent freezing
    local target = findNearestPlayer(root.Position)
    if target then
        humanoid:MoveTo(target.Position, target)
    end
end

If you want them to attack other NPCs, you'll need to modify the function to look through all models in the workspace that could be a character (just like before), except this time ignore the model if it has a particular name (like "Goblin"), like so:

    -- inside the function...
    for _, model in ipairs(workspace:GetChildren()) do
        if model.Name == "Goblin" then continue end
        -- rest of for loop here, using 'model' instead of 'character'
    end
0
although it does work, now the npc seems to detect me from any range calenmaster1 31 — 3y
0
Set closestDist to the maximum range you want (ex `local closestDist = 50` on line 3) and then remove `not closestDist or` on line 11 so that it just says `if dist < closestDist then` chess123mate 5873 — 3y
Ad
Log in to vote
0
Answered by
TGazza 1336 Moderation Voter
3 years ago
Edited 3 years ago

try:

--[[
    function findNearestPlayer(pos)
    grab things at this position code using region3 and insert them into List code
]]
   local Torso = nil
   local Temp2 = nil
    for x = 1, #List do
        Temp2 = List[x]
        if (Temp2.className == "Model") and (Temp2 ~= script.Parent) then
            Temp = Temp2:findFirstChild("HumanoidRootPart")
            Human = Temp2:findFirstChild("Humanoid")
            local plr = Human.Parent.Name -- changed as Human.Name will return "Humanoid"
            if players:FindFirstChild(plr) then
            if (Temp ~= nil) and (Human ~= nil) and (Human.Health > 0) then
                if (Temp.Position - Position).magnitude < Distance then
                    Torso = Temp
                    Distance = (Temp.Position - Position).magnitude
                        end
                    end
                end
            end
            -- return Torso wrong place this will return anything, might be what's causing your npc's to attack each other
        end
    return Torso -- move it to here...
end




while true do

    -- we need to change this to account for a nil returning from our findNearestPlayer function
    local target = findNearestPlayer(script.Parent.HumanoidRootPart.Position)
    if(target ~= nil) then -- Done!

        if not target.Name == ("Goblin") then --how i try to make them not attack eachother
            if target ~= nil then
                script.Parent.Humanoid:MoveTo(target.Position, target)
            end
        end
    end
end

Hope this helps! :)

0
it tells me that there is an extra end statment, but they i remove it and it says everything is wrong :( calenmaster1 31 — 3y
0
To fix the syntax error: Delete lines 1 and 4 and add two dashes on what becomes the 2nd line (the one that starts with "grab things at", so that it reads "--grab things at") chess123mate 5873 — 3y
0
However, this script's logic isn't quite right because if a Goblin is nearby, target.Name will be "Goblin" so that NPC will do nothing. That name check needs to occur in the findNearestPlayer function - better yet, only search through player characters. chess123mate 5873 — 3y

Answer this question