AI not forgetting its target

I am currently trying to make an AI that stops chasing a character once it is out of the AI’s view (using rays). However, I have noticed that when jumping across a wall and using a second player as a to-be target, the AI does not follow the new player and stays still waiting for the original player/target to be in view again to chase.

I have traced down the problem to be with the raycasting, as when I test the AI without trying to hide behide cover with two players, when the target moves out of range, it goes to the next target in range without any issues.

If you are confused on how my AI works, here is a quick summary:
The AI looks for any players within lets say a 15 stud radius. It chases that player, again lets say, 30 studs. Once that player leaves the 30 stud radius, only then it will look for a new player. (This is to prevent the AI from rapidly switching between targets, and also so other players cannot put other people in danger and just run away)

The script:

-- Variables for the AI, its humanoid, and destination
local AI = script.Parent
local humanoid = AI.Humanoid

local AI = script.Parent
local humanoid = AI.Humanoid

local target
local cansee

local runanim = script.RunAnim
local loadedrunanim = AI.Humanoid:LoadAnimation(runanim)

--change these
local seedist = 30
local forgetdist = 30

function findNearestTorso(pos)
	local list = game.Workspace:children()
	local torso = nil
	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("HumanoidRootPart")
			human = temp2:findFirstChild("Humanoid")
			if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
				if (temp.Position - pos).magnitude < seedist then
					torso = temp
					--seedist = (temp.Position - pos).magnitude
				end
			end
		end
	end
	return torso
end


local function Raycast(t)
	-- Set an origin and directional vector
	local rayOrigin = AI.HumanoidRootPart.Position
	local rayDirection = t.Position

	-- Build a "RaycastParams" object and cast the ray
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {AI}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	local raycastResult = workspace:Raycast(rayOrigin, rayDirection - rayOrigin, raycastParams)

	if raycastResult then
		local hitPart = raycastResult.Instance
		if hitPart.Parent ~= t.Parent then
			return false
		else
			return true
		end
	end
end


while true do
	wait()
	print(target)
	--get target
	if target == nil then
		target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
	end
	
	--raycast
	if target ~= nil then
		cansee = Raycast(target)
		if cansee == true then
			print("Can reach character")
		elseif cansee == false then
			print("No bueno")
			target = nil
		end
	end
	
	--go
	if target ~= nil and cansee == true and(target.Position - AI.HumanoidRootPart.Position).Magnitude <= forgetdist then
		humanoid:MoveTo(target.Position)
		if loadedrunanim.IsPlaying == false then
			loadedrunanim:Play()
		end
	else
		target = nil
		humanoid:MoveTo(AI.HumanoidRootPart.Position)
		loadedrunanim:Stop()
	end
end

Thankyou for reading

2 Likes

I seen that you changed this to solved, can you reply with the solution please? :joy:

Alright I will try to remember, and also the reason I marked as solved was just incase someone went through their time to realize that I already solved it

Here I go:
I made a table with all the characters that the AI would ignore. When the AI would raycast to the target, if it could not see it, it would add it to the ignore table. Then, in the find nearest torso function, it would filter out everything in that table and not include it. The table would also clear itself every run in the loop.

1 Like

Ahh thats smart and I didn’t think about that!

I was wondering because I am almost the phase of my game where I am going to add hostile NPCs, and I just wanted to know how you fixed this incase I ran into the same issue. Thanks!