Issues with Raycasting and AI

I am currently working on an AI that for now just follows the character. Here is how the AI works:
It can see you from a certain distance (lets say 15 studs), and it chases and targets you unless you get 30 studs away. However, to prevent the AI from trying to chase and target players that are in another room or behind a wall, I am adding a ray that goes from the AI to the target, and if anything is inbetween, it ignores them.

Here’s the issue: The AI is only following me when I am right in its face. I would say the distance seems like ~3 studs, super small. I added a print statement for when it can see and cannot see the player, and it is never printing cannot see and is printing can see when following the player, so I am completely stumped. I have already tried making sure the AI is not counting part of itself as something inbetween it and the character.

The code:

-- Variables for the zombie, 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 = 15
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, 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(0.1)
	--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
		torso = nil
		humanoid:MoveTo(AI.HumanoidRootPart.Position)
		loadedrunanim:Stop()
	end
end
1 Like

The second argument of the raycast uses the direction, not the goal position. To fix this, replace the other line with this:

local raycastResult = workspace:Raycast(rayOrigin, rayDirection - rayOrigin, raycastParams)
1 Like