What do you want to achieve?
I want to make an NPC that chases the nearest target with a humanoid (both players and NPCs) when they get in a certain radius from it.
What is the issue?
I’m not really sure how to do this since i have low scripting experience.
What solutions have you tried so far?
I’ve tried searching for other devforum posts but all of the ones I’ve found just provide a way for an NPC to chase players when what I’m looking for is a way for an NPC to chase both players and other NPCs.
local RS = game:GetService("RunService")
local target
local hrp = script.Parent.HumanoidRootPart
local maxDistance = 50 --Make this whatever you would like
RS.Heartbeat:Connect(function() --Will constantly run the code below
for i, v in pairs(workspace:GetChildren()) do --Go through the objects in workspace
if v:FindFirstChild("Humanoid") and v ~= npc then --If object has a humanoid (so if they are a player or npc)
local potentialTarget = v --Just to simplify the code, this represents v
local potentialTargetDistance = (potentialTarget.HumanoidRootPart.Position - hrp.Position).Magnitude
print(potentialTargetDistance)
if potentialTargetDistance < maxDistance then
if not target then
target = potentialTarget
else
if (target.HumanoidRootPart.Position - hrp.Position).Magnitude > potentialTargetDistance then
target = potentialTarget
end
end
if target then
npc.Humanoid:MoveTo(target.HumanoidRootPart.Position) --Chase enemy
end
end
end
end
end)
--Below is a basic system of attacking. If you don't want it, by all means, don't use it.
local debounce = false --To make sure damage isn't given every nanosecond and has a cooldown
hrp.Touched:Connect(function(hit) --When touched
local humanoid = hit.Parent:FindFirstChild("Humanoid") --Checks if part's parent has a humanoid
if humanoid then --Checks if part's parent has a humanoid
if debounce == false then
debounce = true
humanoid:TakeDamage(15)
task.wait(.1)
debounce = false
end
end
end)
Basically, it’s constantly checking if any targets are close enough to attack. If there’s already a target, then it checks if there’s anybody closer. It uses stuff like a pairs loop, and magnitude.
If there’s any problems or you have any questions about how the code works, I’d be happy to answer! If anyone wants to propose improvements to the code, I’d be happy to hear!
Sorry for the late reply but thanks for providing the code! I didnt mention it earlier (cause i was worried i would break devforum rules) but the NPCs are in a folder while the players are in the workspace. I already have a code that makes the table and changed the code up a bit but im not sure how to delete items (when the target dies) or update the table.
for context, heres the table code:
for _, v in ipairs(workspace:GetChildren()) do
table.insert(objects, v)
end
for _, v in ipairs(workspace.NPCs:GetChildren()) do
table.insert(objects, v)
end
If you want the AI to not attack dead bodies (which I forgot to add, my bad) you should use if potentialTarget.Humanoid.Health > 0 then and put it under local potentialTarget = v
Anyhow, to remove entries from a table, you can use table.remove. However, you need to insert the position of the entry you want to remove; you cant directly remove the entry using table.remove.
For example, if I have a table here: targets = {[1] = "SomeGuy", [2] = "Goofy NPC"} If I wanted to remove “Goofy NPC” from the table then I would have to do: table.remove(targets, targets["Goofy NPC"]) ; for clarification, targets["Goofy NPC"] returns the position of “Goofy NPC” in the table called “targets”.