Raycast is not detecting instances between npc and player.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local npc = script.Parent
RunService.Heartbeat:Connect(function()
for i,v in pairs(Players:GetPlayers()) do
local player = v
local character = v.Character
if character then
local dotProduct = (npc.HumanoidRootPart.Position - character.HumanoidRootPart.Position).Unit:Dot(npc.HumanoidRootPart.CFrame.LookVector)
if math.max(dotProduct) < 0 then
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {npc, character}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local raycastResult = game.Workspace:Raycast(npc.Head.Position, character.Head.Position, raycastParams)
if not raycastResult then
print(player.Name)
end
end
end
end
end)
Your direction is the position of character.Head, while it should be the direction from the origin position. Try (npc.Head.Position - character.Head.Position).Magnitude instead
Are you still checking if raycastResult is nil? If you are, you’re ignoring the valid RaycastResults that actually has the .Instance value. You should probably do this:
if raycastResults then -- Check if a hit is found.
if raycastResults.Instance:IsDescendantOf(character) then -- If the part hit is inside the Character
print(player.Name)
end
end
No. RaycastResults is only given if there is a successful hit that is not part of the blacklist (or when using whitelist, only specific parts included.)
If your ray points at the sky, you get no RaycastResults. You point on a part however, you’ll get a RaycastResults, depending on your blacklist/whitelist. If RaycastResults is nil, you can’t access .Instance, because nil.Instance doesn’t exist.
The better way to detect obstacles is by determining whether or not the Instance that was hit is either an obstacle, or a Player. Therefore, if the part that was detected is anything but like a LeftUpperLeg or Right Arm, we know that part is an obstacle, otherwise the part that was detected belongs to the Player’s character.
but character, which means all characters cause of loop, is already blacklisted, therefore everything that isnt a players’ characters should be ignored, doesnt it?
I rechecked your code, and found out that your Raycast() function has two positional Vector3’s instead of one positional Vector3 and one directional Vector3 (mutliplied to a certain number, acting as the Distance.
I rewrote parts of your script so that the ray actually hits the player’s head.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local npc = script.Parent
RunService.Heartbeat:Connect(function()
for i,v in pairs(Players:GetPlayers()) do
local player = v
local character = v.Character
if character then
local facingVector : Vector3 = (npc.HumanoidRootPart.Position - character.HumanoidRootPart.Position)
local unitFacingVector = facingVector.Unit
local dotProduct = unitFacingVector:Dot(npc.HumanoidRootPart.CFrame.LookVector)
print(dotProduct)
if math.max(dotProduct) < 0 then
local cframeAngle = CFrame.lookAt(npc.HumanoidRootPart.Position, character.HumanoidRootPart.Position):Inverse().LookVector * Vector3.new(-1, -1, 1)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {npc} -- removed player's character
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local raycastResult = game.Workspace:Raycast(npc.Head.Position, cframeAngle * 90, raycastParams) -- facingVector * 30 is the Direction vector. multiplied by 30 for distance.
if raycastResult then
if raycastResult.Instance:IsDescendantOf(character) then
print(player.Name, "found")
end
end
end
end
end
end)