I have an NPC in my game that’s supposed to move only when it’s not being looked at by any player, if 1 or more players are looking at it this means it should not move, however despite checking for every player in the game it only works for the first player who joined who looks at it and if they lose vision of the NPC it will still chase the other players even if they are looking at it, I can’t seem to figure out the reason to this, why does this happen?
local character = script.Parent
local humanoid = character:FindFirstChild("Humanoid")
local root = character:FindFirstChild("HumanoidRootPart")
local detectionDistance = 100
local maxAllowedAngle = math.cos(math.rad(65))
local targetParts = {}
for i,v in pairs(character:GetChildren()) do
if v:IsA("MeshPart") then
table.insert(targetParts, v)
end
end
local lookedAt = false
local speed = 35
humanoid.WalkSpeed = speed
local function isPlayerWithinDistance(player)
local character = player.Character
if not character then
return false
end
for _, targetPart in pairs(targetParts) do
local distance = (targetPart.Position - character.Head.Position).magnitude
if distance <= detectionDistance then
return true
end
end
return false
end
local function isPlayerLooking(player)
local character = player.Character
if not character then
return false
end
for _, targetPart in pairs(targetParts) do
local direction = (targetPart.Position - character.Head.Position).unit
local characterOrientation = character.HumanoidRootPart.CFrame.lookVector
local dotProduct = direction:Dot(characterOrientation)
if dotProduct >= maxAllowedAngle then
return true
end
end
return false
end
local function performRaycast(player)
local character = player.Character
if not character then
return false
end
for _, targetPart in pairs(targetParts) do
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {player.Character}
local raycastResult = workspace:Raycast(
character.Head.Position,
(targetPart.Position - character.Head.Position).unit * (targetPart.Position - character.Head.Position).magnitude,
raycastParams
)
if raycastResult and raycastResult.Instance == targetPart then
print(raycastResult)
return true
end
end
return false
end
local target2 = nil
local function checkHeadDirection()
for _, player in pairs(game.Players:GetPlayers()) do
if isPlayerWithinDistance(player) then
if isPlayerLooking(player) and performRaycast(player) then
lookedAt = true
root.Move.Playing = false
humanoid.WalkSpeed = 0
else
lookedAt = false
if target2 then
root.Move.Playing = true
end
humanoid.WalkSpeed = speed
end
else
lookedAt = false
if target2 then
root.Move.Playing = true
end
humanoid.WalkSpeed = speed
end
end
end
local SimplePath = require(script.SimplePath)
function findNearestTorso(pos)
local list = game.Workspace:children()
local torso = nil
local dist = 10000
local temp = nil
local human = nil
local temp2 = nil
local player = false
for x = 1, #list do
temp2 = list[x]
if (temp2.className == "Model") and (temp2 ~= character) then
temp = temp2:findFirstChild("HumanoidRootPart")
human = temp2:findFirstChild("Humanoid")
if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
if game.Players:GetPlayerFromCharacter(temp2) and (temp.Position - pos).magnitude < dist then
torso = temp
dist = (temp.Position - pos).magnitude
end
end
end
end
return torso
end
local Goal = Vector3.new()
local Path = SimplePath.new(character)
Path.Visualize = false
Path.Blocked:Connect(function()
Path:Run(Goal)
end)
Path.WaypointReached:Connect(function()
Path:Run(Goal)
end)
Path.Error:Connect(function(errorType)
Path:Run(Goal)
end)
local RunService = game:GetService("RunService")
RunService.Heartbeat:Connect(function()
checkHeadDirection()
local target = findNearestTorso(root.Position)
target2 = target
if target and target.Parent:FindFirstChild("Humanoid") then
if target.Parent.Humanoid.Health ~= 0 then
local distance = (target.Position - root.Position).magnitude
Goal = target.Position
Path:Run(Goal)
if distance <= 3 and lookedAt == false then
target.Parent.Humanoid.Health = 0
root.Snap:Play()
end
end
end
end)