Why Ai doesn't see behind transparent objects?

for some reason AI doesn’t see behind transparent blocks
but if goes through them he just breaks

https://streamable.com/xm8fv4

wait(game.Loaded)

local PathfindingService = game:GetService("PathfindingService")

local Bobby = script.Parent
local humanoid = Bobby:WaitForChild("Humanoid")
local Humanoid_Root_Part = Bobby:WaitForChild("HumanoidRootPart")

Humanoid_Root_Part:SetNetworkOwner(nil)

local pathParams = {
	AgentHeight = 5,
	AgentRadius = 3,
	AgentCanJump = true,
}

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
rayParams.FilterDescendantsInstances = {Bobby}

local lastPos
local RANGE = 150
local DAMAGE = 100

local function canSeeTarget(target)
	local orgin = Humanoid_Root_Part.Position
	local direction = (target.HumanoidRootPart.Position - Humanoid_Root_Part.Position).Unit * RANGE
	local ray = workspace:Raycast(orgin, direction, rayParams)

	if ray and ray.Instance and ray.Instance.Transparency < 1 then
		if ray.Instance:IsDescendantOf(target) then
			return true
		else
			return false
		end
	else
		return false
	end
end
local function findTarget()
	local players = game.Players:GetPlayers()
	local maxDistance = RANGE
	local nearestTarget

	for i, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (Humanoid_Root_Part.Position - target.HumanoidRootPart.Position).Magnitude
			
			if distance < maxDistance and canSeeTarget(target) then
				nearestTarget = target
				maxDistance = distance
				humanoid.WalkSpeed = 50
				Bobby.HumanoidRootPart.Walking.Playing = false
				Bobby.HumanoidRootPart.Running.Playing = true
			else
				humanoid.WalkSpeed = 6
				Bobby.HumanoidRootPart.Running.Playing = false
				Bobby.HumanoidRootPart.Walking.Playing = true
			end
		end
	end

	return nearestTarget
end

local function getPath(destination)
	local path = PathfindingService:CreatePath(pathParams)

	path:ComputeAsync(Humanoid_Root_Part.Position, destination.Position)

	return path	
end

local function attack(target)
	local distance = (Humanoid_Root_Part.Position - target.HumanoidRootPart.Position).Magnitude
	local debounce = false
 local player = game.Players:GetPlayerFromCharacter(target)
	if distance > 5 then
		humanoid:MoveTo(target.HumanoidRootPart.Position)
	else
		if debounce == false then
			debounce = true

			target.Humanoid.Health -= DAMAGE
			Bobby.Head.JumpScare:Play()
			game.ReplicatedStorage.Remotes.DeathEvent:FireClient(player)
			task.wait(0.1)
			debounce = false
		end
	end
end

local function walkTo(destination)
	local path = getPath(destination)

	if path.Status == Enum.PathStatus.Success then
		for i, waypoint in pairs(path:GetWaypoints()) do
			path.Blocked:Connect(function()
				path:Destroy()
			end)

			local target = findTarget()

			if target and target.Humanoid.Health > 0 then
				lastPos = target.HumanoidRootPart.Position
				attack(target)
				break
			else
				if waypoint.Action == Enum.PathWaypointAction.Jump then
					humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
				end
				if lastPos then
					humanoid:MoveTo(lastPos)
					humanoid.WalkSpeed = 50
					humanoid.MoveToFinished:Wait()
					lastPos = nil
					humanoid.WalkSpeed = 6
					break
				else
					humanoid:MoveTo(waypoint.Position)
						humanoid.MoveToFinished:Wait()
						end
				end
			end
	else
		return
	end
end

local function patrol()
	local waypoints = workspace.waypoints:GetChildren()
	local randomNum = math.random(1, #waypoints)
	walkTo(waypoints[randomNum])
	end

while task.wait(0.2) do
	patrol()
end
5 Likes

The issue why its not detecting the target through an invisible wall is because of the raycast in the canSeeTarget() function.

In the code it says,

ray and ray.Instance and ray.Instance.Transparency < 1

It then checks to see if the instance is the target, and says it can see the target.
However, if through an invisible wall it will hit the wall from the AI.

A way you can fix this is by creating a folder of invisible walls then adding that to the blacklist, or if its just one just adding that. This will make the raycast go through it to the target.

rayParams.FilterDescendantsInstances = {Bobby, InvisibleWall}
1 Like

thanks it fixed npc not being able to see invisible wall but now i have an issue of an npc
just stopping after he goes through the wall

2 Likes

Create a PathfindingModifer object in the part you want to be ignored. Set PassThrough of the PathfindingModifier to true.

This probably will also solve the problem of the NPC stopping after going through the wall.

Hope this was your solution!

1 Like

I don’t think it’s the transparent part that’s your issue when the NPC stops. It’s something in your script that quits after the distance is less than 5 studs. It does the jumpscare attack but you aren’t setting it back to the walkTo function.

2 Likes

no i tested it only breaks when you go behind a wall

1 Like

i just added them but npc still breaks sadly

wait(game.Loaded)

local PathfindingService = game:GetService("PathfindingService")

local Bobby = script.Parent
local humanoid = Bobby:WaitForChild("Humanoid")
local Humanoid_Root_Part = Bobby:WaitForChild("HumanoidRootPart")

local InvisiblePart1 = workspace.Map.Office.WorkingParts.Door1.DoorPositions.TargetPartUp
local InvisiblePart2 = workspace.Map.Office.WorkingParts.Door1.DoorPositions.TargetPartDown

local InvisiblePart3 = workspace.Map.Office.WorkingParts.Door2.DoorPositions.TargetPartUp
local InvisiblePart4 = workspace.Map.Office.WorkingParts.Door2.DoorPositions.TargetPartDown

Humanoid_Root_Part:SetNetworkOwner(nil)

local pathParams = {
	AgentHeight = 5,
	AgentRadius = 3,
	AgentCanJump = true,
}

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
rayParams.FilterDescendantsInstances = {Bobby, InvisiblePart1, InvisiblePart2, InvisiblePart3, InvisiblePart4}

local lastPos
local RANGE = 150
local DAMAGE = 100

local function canSeeTarget(target)
	local orgin = Humanoid_Root_Part.Position
	local direction = (target.HumanoidRootPart.Position - Humanoid_Root_Part.Position).Unit * RANGE
	local ray = workspace:Raycast(orgin, direction, rayParams)

	if ray and ray.Instance then
		if ray.Instance:IsDescendantOf(target) then
			return true
		else
			return false
		end
	else
		return false
	end
end
local function findTarget()
	local players = game.Players:GetPlayers()
	local maxDistance = RANGE
	local nearestTarget

	for i, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (Humanoid_Root_Part.Position - target.HumanoidRootPart.Position).Magnitude
			
			if distance < maxDistance and canSeeTarget(target) then
				nearestTarget = target
				maxDistance = distance
				humanoid.WalkSpeed = 50
				Bobby.HumanoidRootPart.Walking.Playing = false
				Bobby.HumanoidRootPart.Running.Playing = true
			else
				humanoid.WalkSpeed = 6
				Bobby.HumanoidRootPart.Running.Playing = false
				Bobby.HumanoidRootPart.Walking.Playing = true
			end
		end
	end

	return nearestTarget
end

local function getPath(destination)
	local path = PathfindingService:CreatePath(pathParams)

	path:ComputeAsync(Humanoid_Root_Part.Position, destination.Position)

	return path	
end

local function attack(target)
	local distance = (Humanoid_Root_Part.Position - target.HumanoidRootPart.Position).Magnitude
	local debounce = false
 local player = game.Players:GetPlayerFromCharacter(target)
	if distance > 5 then
		humanoid:MoveTo(target.HumanoidRootPart.Position)
	else
		if debounce == false then
			debounce = true

			target.Humanoid.Health -= DAMAGE
			Bobby.Head.JumpScare:Play()
			game.ReplicatedStorage.Remotes.DeathEvent:FireClient(player)
			task.wait(0.1)
			debounce = false
		end
	end
end

local function walkTo(destination)
	local path = getPath(destination)

	if path.Status == Enum.PathStatus.Success then
		for i, waypoint in pairs(path:GetWaypoints()) do
			path.Blocked:Connect(function()
				path:Destroy()
			end)

			local target = findTarget()

			if target and target.Humanoid.Health > 0 then
				lastPos = target.HumanoidRootPart.Position
				attack(target)
				break
			else
				if waypoint.Action == Enum.PathWaypointAction.Jump then
					humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
				end
				if lastPos then
					humanoid:MoveTo(lastPos)
					humanoid.WalkSpeed = 50
					humanoid.MoveToFinished:Wait()
					lastPos = nil
					humanoid.WalkSpeed = 6
					break
				else
					humanoid:MoveTo(waypoint.Position)
						humanoid.MoveToFinished:Wait()
						end
				end
			end
	else
		return
	end
end

local function patrol()
	local waypoints = workspace.waypoints:GetChildren()
	local randomNum = math.random(1, #waypoints)
	walkTo(waypoints[randomNum])
	end

while task.wait(0.2) do
	patrol()
end