How do I know if a player is behind a wall?

Hi, I wrote a script for my npc to follow the player. But if suddenly the npc sees that the player is behind the wall, then he does not go. But for some reason, my script does not want to work, my npc pursues the player, even if he is behind a wall. How can I fix this?

My code -

local PlayerHumanoidRootPart
local NpcHumanoidRootPart = script.Parent:WaitForChild("Torso") or script.Parent:WaitForChild("HumanoidRootPart")
local NpcHumanoid = script.Parent:WaitForChild("Humanoid")
local AgroDistance = 50
local Target = nil

local Rayparams = RaycastParams.new()
Rayparams.FilterType = Enum.RaycastFilterType.Whitelist
Rayparams.FilterDescendantsInstances = {PlayerHumanoidRootPart}

local function FindTarget()
	Target = nil
	for _, v in pairs(game.Workspace:GetChildren()) do
		local PlayerHumanoidRootPart = v:FindFirstChild("HumanoidRootPart") or v:FindFirstChild("Torso")
		local PlayerHumanoid = v:FindFirstChild("Humanoid")
		if PlayerHumanoidRootPart and PlayerHumanoid and v.Name ~= script.Parent then
			if (NpcHumanoidRootPart.Position - PlayerHumanoidRootPart.Position).Magnitude < AgroDistance and PlayerHumanoid.Health > 0 then
				Target = PlayerHumanoidRootPart
			end
		end
	end
	return Target
end

while wait(1) do
	local PlayerHumanoidRootPart = FindTarget()
	if PlayerHumanoidRootPart then
		local ray = Ray.new(NpcHumanoidRootPart.Position, PlayerHumanoidRootPart.Position)
		local Hit = game.Workspace:Raycast(ray.Origin, ray.Direction, Rayparams)
		if Hit and Hit.Instance.Name == "Torso" or "HumanoidRootPart" then
			NpcHumanoid:MoveTo(PlayerHumanoidRootPart.Position)
		end
	end
end

If i change “if Hit and Hit.Instance.Name == “Torso” or “HumanoidRootPart” then” to “if Hit and Hit.Instance.Name == PlayerHumanoidRootPart then” then my murder just not moving.

1 Like

You can make Rays ignore certain items. Have the walls in a Folder or Model that you can set the ignore list to.

What if I have a lot of them? why can’t I use the whitelist?

Blacklist the walls, then the Ray won’t be stopped by them. The issue may be with the npc’s script to find a path around the wall at that point though.

That would I not did why the if I write print (ray) he writes always nil

there were few errors with your script; first the the filtertype you were using was whitelist, however since you are using whitelist it would only pick up the players humanoidrootpart and discard any walls blocking it. second the or statement of humanoidrootpart would always return true. third filterdescendantsinstances should be updated or else it stays as nil (i think). fourth ray.Direction did not give you the thing you were looking for sadly.

local PlayerHumanoidRootPart
local NpcHumanoidRootPart = script.Parent:WaitForChild("Torso") or script.Parent:WaitForChild("HumanoidRootPart")
local NpcHumanoid = script.Parent:WaitForChild("Humanoid")
local AgroDistance = 50
local Target = nil

local Rayparams = RaycastParams.new();
Rayparams.FilterType = Enum.RaycastFilterType.Blacklist; --We use blacklist not whitelist

local function FindTarget()
	Target = nil
	for _, v in pairs(game.Workspace:GetChildren()) do
		local PlayerHumanoidRootPart = v:FindFirstChild("HumanoidRootPart") or v:FindFirstChild("Torso")
		local PlayerHumanoid = v:FindFirstChild("Humanoid")
		if PlayerHumanoidRootPart and PlayerHumanoid and v.Name ~= script.Parent then
			if (NpcHumanoidRootPart.Position - PlayerHumanoidRootPart.Position).Magnitude < AgroDistance and PlayerHumanoid.Health > 0 then
				Target = PlayerHumanoidRootPart
			end
		end
	end
	if Target then
		Rayparams.FilterDescendantsInstances = {Target.Parent}; --also try to make it so it gets every players characters
	end
	return Target
end

while wait(1) do
	local PlayerHumanoidRootPart = FindTarget()
	if PlayerHumanoidRootPart then
		local CF = CFrame.new(NpcHumanoidRootPart.Position, PlayerHumanoidRootPart.Position);
		local Hit = game.Workspace:Raycast(CF.p, CF.LookVector * (NpcHumanoidRootPart.Position - PlayerHumanoidRootPart.Position).magnitude, Rayparams);
		if not Hit then --We pretty much make sure the ray did not touch any walls.
			NpcHumanoid:MoveTo(PlayerHumanoidRootPart.Position);
		end
	end
end
2 Likes

Finally someone solved my problem, thank you!