My goal is to create an NPC follow system (I already have the damage system completed). What it should do it if you are within a certain range measured by magnitude you are chased by some NPC's that are within range.
The problem is when a Player first spawns in the NPC chases the player and everything but when the player Dies by something (NPC, another player) the NPC's stop chasing the player. The code works but it stops working sometimes.
Note that this is a ServerScript
in ServerScriptService
local RunService = game:GetService("RunService") local Settings = require(game:GetService("ReplicatedStorage").ModuleScripts.SETTINGS) local Respawn_Time = Settings.BANDIT.RESPAWN_TIME local plrServ = game:GetService('Players') local NPCBackup = game:GetService('ServerStorage').NPCBackup.Bandit local function getClosestPlayer(myPos) local pos, tor = Settings.BANDIT.RANGE for _, plr in pairs(plrServ:GetPlayers()) do if plr.Character then if (plr.Character.PrimaryPart.Position - myPos).Magnitude < pos then pos = (plr.Character.PrimaryPart.Position - myPos).Magnitude tor = plr.Character.PrimaryPart end end end return tor end local function setupNPC(Bandit, BanditPosition) local hum = Bandit.Humanoid local npcPrimaryPart = Bandit.PrimaryPart local targetTorso spawn(function() while wait(1) do targetTorso = getClosestPlayer(npcPrimaryPart.Position) if targetTorso then hum:MoveTo(targetTorso.Position, targetTorso) else return end end end) hum.Died:Connect(function() wait(Settings.BANDIT.RESPAWN_TIME) local cln = NPCBackup:Clone() cln:SetPrimaryPartCFrame(BanditPosition) cln.Parent = workspace.Bandits Bandit:Destroy() setupNPC(cln, BanditPosition) if not cln:FindFirstChild('RobloxAnimation') then local Animation = game:GetService('ServerStorage').Effects.RobloxAnimation:Clone() Animation.Disabled = false Animation.Parent = cln cln.Humanoid.WalkSpeed = Settings.BANDIT.WALKSPEED end end) end for _, Bandit in pairs(workspace.Bandits:GetChildren()) do spawn(function() setupNPC(Bandit, Bandit.PrimaryPart.CFrame) end) end
Hopefully, this problem gets solved, I appreciate any feedback that fixes this issue or improves the code. I try avoiding loops and RunService mostly because I do not know when is the correct time to use a while true do
loop and I know that using a loop incorrectly can be studio crashing and game breaking. Thank you for reading.
Although this may no be correct, here is my answer on it
local RunService = game:GetService("RunService") local Settings = require(game:GetService("ReplicatedStorage").ModuleScripts.SETTINGS) local Respawn_Time = Settings.BANDIT.RESPAWN_TIME local plrServ = game:GetService('Players') local NPCBackup = game:GetService('ServerStorage').NPCBackup.Bandit local function getClosestPlayer(myPos) local pos, tor = Settings.BANDIT.RANGE for _, plr in pairs(plrServ:GetPlayers()) do if plr.Character then if (plr.Character.PrimaryPart.Position - myPos).Magnitude < pos then pos = (plr.Character.PrimaryPart.Position - myPos).Magnitude tor = plr.Character.PrimaryPart end else tor = nil --Added this here so if it can't find the player, it will return nil end end return tor end local function setupNPC(Bandit, BanditPosition) local hum = Bandit.Humanoid local npcPrimaryPart = Bandit.PrimaryPart local targetTorso spawn(function() while wait(1) do targetTorso = getClosestPlayer(npcPrimaryPart.Position) if targetTorso then hum:MoveTo(targetTorso.Position, targetTorso) --Removed the else here end end end) hum.Died:Connect(function() wait(Settings.BANDIT.RESPAWN_TIME) local cln = NPCBackup:Clone() cln:SetPrimaryPartCFrame(BanditPosition) cln.Parent = workspace.Bandits Bandit:Destroy() setupNPC(cln, BanditPosition) if not cln:FindFirstChild('RobloxAnimation') then local Animation = game:GetService('ServerStorage').Effects.RobloxAnimation:Clone() Animation.Disabled = false Animation.Parent = cln cln.Humanoid.WalkSpeed = Settings.BANDIT.WALKSPEED end end) end for _, Bandit in pairs(workspace.Bandits:GetChildren()) do spawn(function() setupNPC(Bandit, Bandit.PrimaryPart.CFrame) end) end
You may have to return the torso's position from the getClosestPlayer function, but I don't know for sure. Hopefully this works (which it probably doesn't)! :D
Use this:
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 = 10 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("Humanoid") 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.Enemy:MoveTo(target.Position, target) end end