Hello! I am currently trying to make an enemy robot NPC that chases after you if you are in the right vicinity. However, this does not work, and I’m not sure why.
Here is my code:
local Robot = script.Parent
local debounce = false
local Hitbox = Robot:WaitForChild("Hitbox")
Hitbox.Touched:Connect(function(hit)
if hit and game.Players:GetPlayerFromCharacter(hit.Parent) then
if debounce == false then
debounce = true
local Explosion = Instance.new("Explosion")
Explosion.Parent = game.Workspace
Explosion.Position = Hitbox.Position
--Explosion.BlastRadius = 10
--Explosion.ExplosionType = Enum.ExplosionType.Craters
task.wait(.25)
debounce = false
end
end
end)
function FindPlayer(Position)
local List = game.Workspace:GetChildren()
local Torso = nil
local Distance = 50
local HumanoidRootPart = nil
local Humanoid = nil
local Player = nil
for i = 1, #List do
Player = List[i]
if (Player.ClassName == "Model") and (Player ~= script.Parent) then
HumanoidRootPart = Player:WaitForChild("HumanoidRootPart")
Humanoid = Player:WaitForChild("Humanoid")
if (HumanoidRootPart ~= nil) and (Humanoid ~= nil) and (Humanoid.Health > 0) then
if (HumanoidRootPart.Position - Position).Magnitude < Distance then
Torso = HumanoidRootPart
Distance = (HumanoidRootPart.Position - Position).Magnitude
end
end
end
end
return Torso
end
while true do
task.wait(1)
local Target = FindPlayer(script.Parent.HumanoidRootPart.Position)
if Target ~= nil then
script.Parent.Humanoid:MoveTo(Target.Position, Target)
end
end
local Copy = script.Parent:Clone()
for i,v in pairs(Robot:GetChildren()) do
if v:IsA("Humanoid") then
Humanoid = v
end
end
if Humanoid then
Humanoid.Died:Connect(function()
task.wait(5)
Copy.Parent = Robot.Parent
Copy:MakeJoints()
Robot:Destroy()
end)
else
warn("Cannot find Humanoid")
end
No errors appear in the output. Also, whenever the explosion in the .Touched function fires, it destroys the NPC. Is there anyway to fix this? Thank you for your help and have a wonderful day!
Humanoid.Died:Connect(function()
local Copy = script.Parent:Clone()
Copy.Parent = Robot.Parent
task.wait(5)
if Humanoid.Parent == nil then
Copy:MakeJoints()
Robot:Destroy()
end
end)
Maybe try this? I hope it helps, but it might not.
Hi. Sorry about the wait. I’m not great at using PathfindingService, so I made this for you instead. I hope it works!
local Robot = script.Parent
local debounce = false
local Hitbox = Robot:WaitForChild("Hitbox", math.huge)
local Players = game.Players or game:GetService("Players")
local RunService = game:GetService("RunService")
Hitbox.Touched:Connect(function(hit)
if hit and Players:GetPlayerFromCharacter(hit.Parent) then
if debounce == false then
debounce = true
local Explosion = Instance.new("Explosion")
Explosion.Parent = game.Workspace
Explosion.Position = Hitbox.Position
Explosion.BlastRadius = 0
Explosion.BlastPressure = 0
Explosion.DestroyJointRadiusPercent = 0
task.wait(.25)
debounce = false
end
end
end)
function FindPlayer(Position)
local List = game.Workspace:GetDescendants()
local Torso = nil
local Distance = 50
local HumanoidRootPart = nil
local Humanoid = nil
local Player = nil
for i = 1, #List do
Player = List[i]
if (Player.ClassName == "Model") and (Player ~= script.Parent) then
HumanoidRootPart = Player:WaitForChild("HumanoidRootPart", math.huge)
Humanoid = Player:WaitForChild("Humanoid", math.huge)
if (HumanoidRootPart ~= nil) and (Humanoid ~= nil) and (Humanoid.Health > 0) then
if (HumanoidRootPart.Position - Position).Magnitude < Distance then
Torso = HumanoidRootPart
Distance = (HumanoidRootPart.Position - Position).Magnitude
end
end
end
end
return Torso
end
local ShouldRun = true
RunService.Heartbeat:Connect(function(DT)
if ShouldRun == true then
ShouldRun = false
task.wait(1)
local Target = FindPlayer(Robot.HumanoidRootPart.Position)
if not Target then
return
end
Robot.Humanoid:MoveTo(Target.Position, Target)
ShouldRun = true
end
end)
for i, v in ipairs(Robot:GetChildren()) do
if v:IsA("Humanoid") then
local Humanoid = v
if not Humanoid then
warn("Humanoid not found.")
return
end
Humanoid.Died:Connect(function()
task.delay(5, function()
local Copy = Robot:Clone()
Copy.Parent = Robot.Parent
Copy:MakeJoints()
Robot:Destroy()
end)
end)
end
end
Hitbox.Touched:Connect(function(hit)
if hit and Players:GetPlayerFromCharacter(hit.Parent) and hit.Parent:FindFirstChild("Humanoid") then
local Human = hit.Parent.Humanoid
if debounce == false and Human then
debounce = true
Human.Health -= 100 -- change this to whatever number you want.
local Explosion = Instance.new("Explosion")
Explosion.Parent = game.Workspace
Explosion.Position = Hitbox.Position
Explosion.BlastRadius = 0
Explosion.BlastPressure = 0
Explosion.DestroyJointRadiusPercent = 0
task.wait(.25)
debounce = false
end
end
end)
If you want this to instakill, just remove the “-=” and replace it with Human.Health = 0
If you want to control who takes damage from an explosion, you have to use Explosion.Hit. If you only want players to take damage, you would have to use a function such as:
if game.Players:GetPlayerFromCharacter(part.Parent) then
part:BreakJoints()
end
Sorry for the lack of communication. I’m looking into the issue. It might take me a while. You can try watching a tutorial for PathfindingService, as it actually is better than the script that I gave to you for following a player.
That while loop is the cause of your issue. Wrap it in a task.spawn and it’ll work:
task.spawn(function()
while true do
task.wait(1)
local Target = FindPlayer(script.Parent.HumanoidRootPart.Position)
if Target ~= nil then
script.Parent.Humanoid:MoveTo(Target.Position, Target)
end
end
end)
Or alternatively, move the loop to the very end of the script and it’ll also work.
It didn’t make my NPC move. Did I do something wrong?
local Players = game:GetService("Players")
local Robot = script.Parent
local debounce = false
local Hitbox = Robot:WaitForChild("Hitbox")
Hitbox.Touched:Connect(function(hit)
if hit and Players:GetPlayerFromCharacter(hit.Parent) and hit.Parent:FindFirstChild("Humanoid") then
local Humanoid = hit.Parent.Humanoid
if debounce == false and Humanoid then
debounce = true
Humanoid.Health -= 100 -- change this to whatever number you want.
local Explosion = Instance.new("Explosion")
Explosion.Parent = game.Workspace
Explosion.Position = Hitbox.Position
Explosion.BlastRadius = 0
Explosion.BlastPressure = 0
Explosion.DestroyJointRadiusPercent = 0
task.wait(.25)
debounce = false
end
end
end)
function FindPlayer(Position)
local List = game.Workspace:GetChildren()
local Torso = nil
local Distance = 50
local HumanoidRootPart = nil
local Humanoid = nil
local Player = nil
for i = 1, #List do
Player = List[i]
if (Player.ClassName == "Model") and (Player ~= script.Parent) then
HumanoidRootPart = Player:WaitForChild("HumanoidRootPart")
Humanoid = Player:WaitForChild("Humanoid")
if (HumanoidRootPart ~= nil) and (Humanoid ~= nil) and (Humanoid.Health > 0) then
if (HumanoidRootPart.Position - Position).Magnitude < Distance then
Torso = HumanoidRootPart
Distance = (HumanoidRootPart.Position - Position).Magnitude
end
end
end
end
return Torso
end
local Copy = script.Parent:Clone()
for i,v in pairs(Robot:GetChildren()) do
if v:IsA("Humanoid") then
Humanoid = v
end
end
if Humanoid then
Humanoid.Died:Connect(function()
task.wait(5)
Copy.Parent = Robot.Parent
Copy:MakeJoints()
Robot:Destroy()
end)
else
warn("Cannot find Humanoid")
end
task.spawn(function()
while true do
task.wait(1)
local Target = FindPlayer(script.Parent.HumanoidRootPart.Position)
if Target ~= nil then
script.Parent.Humanoid:MoveTo(Target.Position, Target)
end
end
end)
local Players = game:GetService("Players")
local Robot = script.Parent
local debounce = false
local maxDistance = 50
local Hitbox = Robot:WaitForChild("Hitbox")
Hitbox.Touched:Connect(function(hit)
if hit and Players:GetPlayerFromCharacter(hit.Parent) and hit.Parent:FindFirstChild("Humanoid") then
local Humanoid = hit.Parent.Humanoid
if debounce == false and Humanoid then
debounce = true
Humanoid.Health -= 100 -- change this to whatever number you want.
local Explosion = Instance.new("Explosion")
Explosion.Parent = game.Workspace
Explosion.Position = Hitbox.Position
Explosion.BlastRadius = 0
Explosion.BlastPressure = 0
Explosion.DestroyJointRadiusPercent = 0
task.wait(.25)
debounce = false
end
end
end)
local function FindNearestPlayer(Position)
local closestDistance = maxDistance
local closestPosition = nil
for i, player in ipairs(Players:GetPlayers()) do
local Character = player.Character
local HumanoidRootPart = Character and Character:FindFirstChild("HumanoidRootPart")
if not HumanoidRootPart then
continue
end
local distance = (HumanoidRootPart.Position - Position).Magnitude
if distance < closestDistance then
closestDistance = distance
closestPosition = HumanoidRootPart.Position
end
end
return closestPosition
end
local Copy = script.Parent:Clone()
Robot:WaitForChild("Humanoid").Died:Connect(function()
task.wait(5)
Copy.Parent = workspace
Robot:Destroy()
end)
while task.wait(1) and Robot:IsDescendantOf(workspace) do
local Target = FindNearestPlayer(script.Parent.HumanoidRootPart.Position)
if Target then
script.Parent.Humanoid:MoveTo(Target)
end
end
If there are any errors, tell me, I’ll fix them as soon as I get back.