AI controller script for monsters

I watched tutorials on how to create this script. Honestly its way over my head as a new scripter. The script works fine. But it has one problem I have been trying to fix. If the monster kills the player, the monster stands in the same spot attacking the air where the dead player was. It needs a check to see if the player is dead and then a return to spawn location reset.

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() do

	if target 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

something like this?

			else 
				if target.Health >0 then 
					print("returning home")
					hum:MoveTo(spawnPos.Value)

2 Likes

I tried adding to the script but it breaks the movement.

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() do

	if target 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
			else  -- added this line
				if target.Health >0 then 
					print("returning home")
					hum:MoveTo(spawnPos.Value) --- to this line.
				end
			end

		end

	end

end

Does your game use the Humanoid instance for health or it’s a custom-made health system?

1 Like

Humanoid default health system.

This should fix it

while wait() do

	if target 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("returning home")
                        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 and target.Humanoid.Health > 0 then
				print("Targeting "..v.Name)
				target = char
			end

		end

	end

end
1 Like

try this?

while wait() do
	local targetIsInWorkspace
	pcall(function()
		targetIsInWorkspace = target.Parent == game.Workspace
	end)
	if targetIsInWorkspace then
		--ur code
	else
		--insert code
	end
end
1 Like

Unfortunately this resulted in the monsters standing in place and not attacking.

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

local target = nil

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

	if target 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
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() 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
2 Likes

I am doing more testing with multiple people, but when I am by myself, this script does the following.

The monster kills me and stays in the same spot after I die. When I return and get within his sight range, he then returns to his spawn location and then starts attacking again.

What is keeping him from returning home after the player dies?

Actually yeah this works much better and I think it will be my final version. If I make it so they return home after they kill someone, they will be running back home if there are other players attacking them.

Thank you for this.