More AI help, different issue with targets

After my NPC’s kill a player they just stand there attacking the air where the dead player was.

local hum = script.Parent:WaitForChild("Humanoid")
local root = script.Parent:WaitForChild("HumanoidRootPart")
local spawnPos = script.Parent:WaitForChild("SpawnPosition")

local visionRange = 60
local attackRange = 3
local abandonRange = 50
local abandonRangeFromHome = 200

local target = nil

while wait(1) do
	local targetIsInWorkspace
	pcall(function()
		targetIsInWorkspace = target.Parent == game.Workspace
	end)

	if targetIsInWorkspace then
		--calculate distance and attack player
		local plrRoot = target.HumanoidRootPart
		local distance = (root.Position - plrRoot.Position).magnitude
		local distancefromhome = (spawnPos.Value - plrRoot.Position).magnitude

		hum:MoveTo(plrRoot.Position - CFrame.new(root.Position, plrRoot.Position).LookVector * attackRange)

		if distance <= attackRange +2 then
			script.AttackRemote:Fire(plrRoot)
		end

		if distance > abandonRange then
			print("Abandoning Target")
			target = nil
			hum:MoveTo(spawnPos.Value)
		end

		if distancefromhome > abandonRangeFromHome then
			print("Abandoning Target")
			target = nil
			hum:MoveTo(spawnPos.Value)
		end
		
	else
		--see if any players are in range
		for i,v in pairs(game.Players:GetChildren()) do

			if not game.Workspace:FindFirstChild(v.Name) then continue end
			local char = game.Workspace[v.Name]
			local plrRoot = char.HumanoidRootPart

			local distance = (root.Position - plrRoot.Position).magnitude
			local distancefromhome = (spawnPos.Value - plrRoot.Position).magnitude

			if distance < visionRange and distancefromhome < abandonRangeFromHome then
				print("Targeting "..v.Name)
				target = char
			end

		end

	end

end

I added this to the script, but the NPC’s stopped attacking people.

		if target.Health <=0 then
			print("Target Died")
			target = nil
			hum:MoveTo(spawnPos.Value)

Im trying to get the monsters to go back to spawn position if they kill the target. Or actually find a new target or move back to spawn position.

1 Like

i think you need to get health from humanoid instead

if target.Humanoid.Health <= 0 then
1 Like

I tried adding it like this but he wont attack now.

local hum = script.Parent:WaitForChild("Humanoid")
local root = script.Parent:WaitForChild("HumanoidRootPart")
local spawnPos = script.Parent:WaitForChild("SpawnPosition")

local visionRange = 60
local attackRange = 3
local abandonRange = 50
local abandonRangeFromHome = 200

local target = nil

while wait(1) do
	local targetIsInWorkspace
	pcall(function()
		targetIsInWorkspace = target.Parent == game.Workspace
	end)

	if targetIsInWorkspace then
		--calculate distance and attack player
		local plrRoot = target.HumanoidRootPart
		local distance = (root.Position - plrRoot.Position).magnitude
		local distancefromhome = (spawnPos.Value - plrRoot.Position).magnitude

		hum:MoveTo(plrRoot.Position - CFrame.new(root.Position, plrRoot.Position).LookVector * attackRange)

		if distance <= attackRange +2 then
			script.AttackRemote:Fire(plrRoot)
		end

		if distance > abandonRange then
			print("Abandoning Target")
			target = nil
			hum:MoveTo(spawnPos.Value)
		end

		if distancefromhome > abandonRangeFromHome then
			print("Abandoning Target")
			target = nil
			hum:MoveTo(spawnPos.Value)
		end
		
		if target.Humanoid.Health <= 0 then
			print("Target Died")
			target = nil
			hum:MoveTo(spawnPos.Value)
		end
		
	else
		--see if any players are in range
		for i,v in pairs(game.Players:GetChildren()) do

			if not game.Workspace:FindFirstChild(v.Name) then continue end
			local char = game.Workspace[v.Name]
			local plrRoot = char.HumanoidRootPart

			local distance = (root.Position - plrRoot.Position).magnitude
			local distancefromhome = (spawnPos.Value - plrRoot.Position).magnitude

			if distance < visionRange and distancefromhome < abandonRangeFromHome then
				print("Targeting "..v.Name)
				target = char
			end

		end

	end

end

Am I putting it in the wrong place, or is it just wrong?

There is no error on output?
(())

I have just tested change this

to this

if target then --make sure it still follow player
	if target.Humanoid.Health <= 0 then 
		print("Target Died")
		target = nil
		hum:MoveTo(spawnPos.Value)
	end
end

EDIT: Small advice change wait() to task.wait() it do the same thing but better

1 Like

Thank you so much for that help. It works great. I have been working on this script for months being self taught and piecing things together slowly.

I only have one more thing to learn. I want to make the monsters teleport back to the spawn position if they kill someone or if they run to far away. This will keep players from being able to get them stuck in terrain and cheese them.

I think I have to change the MoveTo(spawnPos.Value) lines to TeleportTo(spawnPos.Value) And get the teleport service function. I really don’t know, im throwing out ideas. I might start another thread on that subject later.

Would it be difficult to have the monster look for a new target after killing someone and if there isn’t a new target then return to spawn position?

1 Like

if you want to teleport monster to spawn point you need to change monster HumanoidRootPart Position by doing

script.Parent.HumanoidRootPart.Position = spawnPos.Value

So replace

hum:MoveTo(spawnPos.Value)

with

script.Parent.HumanoidRootPart.Position = spawnPos.Value

?

yes
(a 30 c limit asadassafasfwadrfasfas)

1 Like

i edited this post because I figured out my question. But for some reason the teleport to spawn position causes a lot of glitches, the monster eventually just vanishes.

Maybe the best solution is a 1 minute timer that resets the monster to spawn position no matter what.

Alright then you can use :PivotTo() to teleport model instead but you need to save CFrame when monster first spawn like this

local hum = script.Parent:WaitForChild("Humanoid")
local root = script.Parent:WaitForChild("HumanoidRootPart")
local spawnPos = script.Parent:WaitForChild("SpawnPosition")


local visionRange = 60
local attackRange = 3
local abandonRange = 50
local abandonRangeFromHome = 200

--New line
local SavedSpawnCFrame = root.CFrame --We saved first CFrame when it spawn (?)

and when you want to teleport you can do this

if distance > abandonRange then
	print("Abandoning Target")
	target = nil
	script.Parent:PivotTo(SavedSpawnCFrame)
end

then it should work

1 Like

Ahh yes PivotTo works without issues. Thanks again. You are awesome.

Do you know how to turn his spawn position 90 degrees? I want to control what way he faces by default. I tried turning the spawn position part but he is not oriented with its direction.

local serverStorage = game:GetService("ServerStorage")
local barbarian = serverStorage:WaitForChild("Barbarian"):Clone()
barbarian.HumanoidRootPart.Position = script.Parent.Position


local spawnpos = barbarian:WaitForChild("SpawnPosition")
spawnpos.Value = script.Parent.Position

local respawntime = 25


barbarian.Parent = game.Workspace

barbarian.Humanoid.HealthChanged:Connect(function(newHealth)
	if newHealth <= 0 then
		barbarian:Destroy()
		wait(respawntime)
		script.Disabled = true
		script.Disabled = false
	end
end)

I have seen your post about that i will try to find way and post there cuz it’s unrelate to this post

Thanks, ive been trying a lot of cframe positions and nothing worked so far.