Vision based pathfinding can detect players through walls

Okay, for this reply and the one above it, I have a video showing what the problem is, and what happens via prints:

https://drive.google.com/drive/folders/1uMvEvJ9JXiL0sGeK0JWyvU7Jikhv2g_C?usp=sharing

the main issue, is that the script is constantly detecting the player’s torso, despite having sight checks to see if they can even see the target (the example being me in the video), and that it will not stop following you until you either:

  • Hide in a locker to get them to stop the chase
  • get tp’d by one of the enemies (the main gimmick being they teleport you randomly across the school)

It stems from that, and kind of doesn’t work the intended way it was supposed to.

by the way, if you need the whole script for context: it is below:

-- Misc ---

script.Parent.PrimaryPart:SetNetworkOwner(nil)

--- Variables ---

local Waypoints = game.Workspace:WaitForChild("Waypoints")
local myhuman = script.Parent:WaitForChild("NPC")
local myroot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")

--- Functions ---

function walkrandomly() -- Npc wandering around
	
	local RandWaypoint = Waypoints:GetChildren()[math.random(1, #Waypoints:GetChildren())]
	local goal = RandWaypoint.Position
	
	local PathParams = {
		AgentHeight = 6,
		AgentRadius = 3.5,
		AgentCanJump = true,
		
		Costs = {
			Water = 100,
			DangerZone = math.huge
		}
	}
	
	local path = game:GetService("PathfindingService"):CreatePath(PathParams)
	path:ComputeAsync(myroot.Position, goal)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				myhuman.Jump = true -- Lets the NPC jump if needed
			end
				
				local target = findtarget()
				
				if target and target.Parent.Humanoid.Health > 0 then
					myhuman.WalkSpeed = 17
					findpath(target)
					break
				else
					myhuman.WalkSpeed = 14
					myhuman:MoveTo(waypoint.Position)
					local timeout = myhuman.MoveToFinished:Wait(1)


					if not timeout then
						print("Whoops, Stuck.")
						myhuman.Jump = true
						walkrandomly()
					end
				end
		end
	else
		print("Path failure D:, Finding new path...")
		wait(1)
		walkrandomly()
	end
end

function findpath(target)
	local PathParams = {
		AgentHeight = 6,
		AgentRadius = 3.5,
		AgentCanJump = true,
		
		Costs = {
			Water = 100,
			DangerZone = math.huge
		}
	}
	local path = game:GetService("PathfindingService"):CreatePath(PathParams)
	path:ComputeAsync(myroot.Position, target.Position)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				myhuman.Jump = true
			end
			myhuman:MoveTo(waypoint.Position)
			local timeout = myhuman.MoveToFinished:Wait(1)
			if not timeout then
				myhuman.Jump = true
				findpath(target)
				break
			end
			if checksight(target) then
				repeat
					myhuman:MoveTo(target.Position)
					wait(0.1)
					if target == nil then
						break
					elseif target.Parent == nil then
						break
					end
				until checksight(target) == false or myhuman.Health < 1 or target.Parent:FindFirstChildWhichIsA("Humanoid").Health < 1
				break
			end
			if (myroot.Position - waypoints[1].Position).Magnitude > 20 then
				findpath(target)
				break
			end
		end
	end
end

function checksight(target)
	local raycastparams = RaycastParams.new()
	raycastparams.FilterDescendantsInstances = {script.Parent, workspace.NPCS}
	raycastparams.FilterType = Enum.RaycastFilterType.Exclude
	local RaycastResult = workspace:Raycast(myroot.Position, (target.Position - myroot.Position).Unit * 40, raycastparams)
	if RaycastResult then
		local Hitpart = RaycastResult.Instance
		if Hitpart:IsDescendantOf(target.Parent) and math.abs(Hitpart.Position.Y - myroot.Position.Y) < 1 then
			print("Target Sighted")
			return true
		else
			print("No target")
			return false
		end
	end
	return false
end

function findtarget()
	local dist = 50 -- zombie detection range, change to what you want
	local target = nil
	local potentialtargets = {}
	local seetargets = {}
	for i,v in ipairs(workspace:GetChildren()) do
		local human = v:FindFirstChild("Humanoid")
		local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
		if human and torso and v.Name ~= script.Parent.Name then
			if (myroot.Position - torso.Position).Magnitude < dist and human.Health > 0 then
				table.insert(potentialtargets,torso)
			end
		end
	end
	if #potentialtargets > 0 then
		for i,v in ipairs(potentialtargets) do
			if checksight(v) then
				table.insert(seetargets, v)
			elseif #seetargets == 0 and (myroot.Position - v.Position).Magnitude < dist then
				target = v
				dist = (myroot.Position - v.Position).Magnitude
			end
		end
	end
	if #seetargets > 0 then
		dist = math.huge
		for i, v in ipairs(seetargets) do
			if (myroot.Position - v.Position).Magnitude < dist then
				target = v
				dist = (myroot.Position - v.Position).Magnitude
			end
		end
	end
	print(target)
	return target
end


function main()
	local target = findtarget()
	if target then
		myhuman.WalkSpeed = 17 -- Change to what you set your Zombie's walkspeed to
		findpath(target)
	else
		myhuman.WalkSpeed = 14
		walkrandomly()
	end
end

while wait(0.1) do
	if myhuman.Health < 1 then
		break
	end
	main()
end
1 Like