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

How do I make NPCs kill players not each other?

Asked by 6 years ago
Edited 6 years ago

I am currently trying to make a game that includes Enemy NPCs.

I have a follow script on these NPCs but they are not targeting me, instead they are targeting each other when they spawn.

I know I need to change the name of NPCs Humanoids but Im really new to scripting and i cant seem to find where to change the name to.

( also I want to make different groups of NPCs so I need to know where to change the name, please dont just send me a fixed script )

here is the current follow script I have on the NPCs:

local larm = script.Parent:FindFirstChild("Left Arm")
local rarm = script.Parent:FindFirstChild("Right Arm")

function findNearestTorso(pos)
    local list = game.Workspace:children()
    local torso = nil
    local dist = 100
    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("Torso")
            human = temp2:findFirstChild("NPC")
            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

while true do
    wait(0.1)
    local target = findNearestTorso(script.Parent.Torso.Position)
    if target ~= nil then
        script.Parent.Humanoid:MoveTo(target.Position, target)
    end
end

2 answers

Log in to vote
0
Answered by
Viking359 161
6 years ago
Edited 6 years ago

Use an if statement after you check if there is a humanoid

players = game:GetService("Players")
--check for the humanoid here
local plr = --[[whateveritisitdetectshere]].Name
if players:FindFirstChild(plr) then --you can also make a table and check the table for the name if you want it to find a certain npc
--rest of the stuff

You can change the name of an npc's humanoid by going into the explorer and clicking on it's humanoid then changing its name. If you do that, you might have to rescript a lot of other stuff.

Ad
Log in to vote
0
Answered by 6 years ago

You describe wanting to have multiple groups of NPCs, presumably that attack each other. To do this, you'll need to change the part of the script that determines what to target. First, we need a way for the NPC to know who it should attack. My recommendation is to have an NPC StringValue as a child of each NPC with the "rule" (which we will script in a moment) that if two NPCs have the same NPC.Value, they are allies. In this way you can create groups of NPCs.

Your current script goes through each child of the workspace and looks for the following conditions:

  1. The child must be a Model
  2. The child mustn't be the script's parent (ie don't target yourself)
  3. It must have a Torso
  4. It must have a child named "NPC" (which it assumes is the Humanoid) and it must be alive
  5. It must be closer than the current best dist

We don't really need requirement #1. We will change the 4th requirement a bit so that "NPC" is now a StringValue and, if it exists, its value must not equal the current NPC's value. (You should rename the NPC Humanoid to just "Humanoid" so that it will be consistent.) Because of our change to #4, we no longer need #2 (because NPC.Value == NPC.Value for the same NPC)

Your script also uses many deprecated methods. Improved script:

local larm = script.Parent:WaitForChild("Left Arm")
local rarm = script.Parent:WaitForChild("Right Arm")
local ourNPC = script.Parent:WaitForChild("NPC")
local updateTime = 0.5
function findNearestTorso(pos)
    local ch = workspace:GetChildren()
    local bestDist = 100
    local dist, torso, bestTorso, npc, c, h -- c is child, h is humanoid
    for i = 1, #ch do
        c = ch[i]
        torso = c:FindFirstChild("Torso")
        if torso then
            h = c:FindFirstChild("Humanoid")
            if h and h.Health > 0 then
                npc = c:FindFirstChild("NPC")
                --[[ Consider this target in two cases:
                    1. There is no 'NPC' value (ie it is a player)
                    2. There is an 'NPC' value, but its value is different from 'ourNPC's (it is an enemy).]]
                if not npc or npc.Value ~= ourNPC.Value then
                    --Valid target; is it closer than current best target?
                    dist = (torso.Position - pos).magnitude
                    if dist < bestDist then
                        bestDist = dist
                        bestTorso = torso
                    end
                end
            end
        end
    end
    return bestTorso
end

wait(math.random() * updateTime) -- try to make it so that if multiple NPCs spawn at the same time, they update at different times (try to minimize lag spikes)
while true do
    local target = findNearestTorso(script.Parent.Torso.Position)
    if target then
        script.Parent.Humanoid:MoveTo(target.Position, target)
    end
    wait(updateTime)
end

Note that the first two lines can be removed if you provided the full script, as larm and rarm are not in use.

0
he said attack players not eachother AlphaFlame5 -1 — 4y

Answer this question