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
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.
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.
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