Enemy NPC not respawning

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! :slight_smile:

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.

1 Like

Sadly it didn’t work. I’m not sure why, though.

I’ve had problems with move scripts before, as they are definitely not my strong suit lol. Would using PathfindingService work better for this?

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

Just copy and paste this into your code.

1 Like

It works for the most part. The robot doesn’t take any damage from the explosion, but now the player doesn’t. How would you adjust this?

Apologies for the delay again. Here you go.

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

1 Like

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
1 Like

It worked! Thank you!

Do you have any ideas on how to make it move and follow the player?

1 Like

I copy and pasted your code and I got this error:
Workspace.Script:43: attempt to index nil with 'MoveTo'
It has to do with this line:

NPC:MoveTo(Target.Position)

See if this works

if NPC:IsA("Humanoid") then
    NPC:MoveTo(Target.Position)
end
1 Like
Workspace.RobotServer:43: attempt to index nil with 'IsA' 

Sorry but that didn’t work either.

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.

1 Like

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.

1 Like

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)

I’m fairly sure you don’t need :MakeJoints.

Code:

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.

There are no errors in the output. I copy and pasted your code, but it still doesn’t work.