How would I make a raycast that goes in all directions?

Hello I am making a fps game and want to make a gun npc but i can figure out how to raycast more than just forward. I want the npc to see in all directions. Any help?

while wait() do

	local ray = Ray.new(origin.Position, origin.CFrame.lookVector * DISTANCE) -- Calculating the raycast.

	local hit = workspace:FindPartOnRay(ray, origin.Parent) -- Creating a ray to see what the npc sees.

	if hit then  
		for _, player in pairs(Players:GetPlayers()) do -- We're going to loop through all players to see if the npc sees any of them.
			if player.Character and player.Character:IsAncestorOf(hit) then 
				-- Handle what happens here. 
				print("I see " .. player.Name)
				break
			end
		end
	end 

end

You cannot fire one single raycast in multiple directions. Instead, fire one for each player.

Loop through all players, fire a raycast to each single player using their HumanoidRootParts position as a target.
Blacklist the targeted players character for each ray.

If your raycast DID hit something, it means something is in the way.
If it did NOT hit something, you’ve got your player in sight.

Do keep the following things in mind though:

-Not hitting something can also mean that the raycast reached its maximum distance

-If you only blacklist the targeted player for each ray, then players can block the view to other players by standing in front of your NPCs

-Firing just one ray per player, and using their HumanoidRootParts position as a target, means that if they only show their arm behind a wall for example, the NPC will not see them

I understand what you mean but I am new to this stuff so how would I fire one to each player?

How to loop through players

How to find a players HumanoidRootPart

Also look at more information to raycasts.

Intro to Raycasting

RaycastParams (So you can blacklist their characters)

this video shows npc view then just use a ray to check if the player is behind a wall or not

I think that is not what he means, he wants to fire a raycast in all directions so they have a full range of view.

like in an arc? an arc of rays?

The way I understood him is in my first reply, although it could be I misunderstood him. Perhaps he can answer this.

while task.wait() do
	for _, player: Player in ipairs(Players:GetPlayers()) do -- We're going to loop through all players to see if the npc sees any of them.
		local character: Model = player.Character
		if character then 
			local HumanoidRootPart: BasePart = character:FindFirstChild("HumanoidRootPart")
			if HumanoidRootPart then
				local rayParams: RaycastParams = RaycastParams.new()
				local result = workspace:Raycast(origin.Position, CFrame.lookAt(origin, HumanoidRootPart.Position).LookVector * DISTANCE, rayParams)
				--result will return the part that is hit, otherwise nil
				if result and result.Instance:IsDescendantOf(character) then  
					-- Handle what happens here. 
					print("I see " .. player.Name)
					break
				end
			end
		end
	end 
end

White listing the player means that if the player if behind the wall the npc will still see them, wouldnt they?

I’m not really sure what behavior he is looking for. I can take out the whitelist though, and just check if it is a descendant of character.

He said in all directions + like realschnappi said, a ray will have to be casted to check if the player is behind an obstacle.

as I am new to this type of raycasting it’s hard for me to understand why I can’t fix this error

Screen Shot 2022-07-08 at 8.27.44 PM

Checking if it is a descendant is possible too, but i imagine that the blacklist version has less of a performance impact.

I was thinking more of this

heres the code:

local arcAngle = 90
local distance = 10

while task.wait() do
	for a=0, arcAngle, 1 do

		local angle = a-(arcAngle/2)

		local dir = Vector3.new(
			math.cos(math.rad(angle)),
			0,
			math.sin(math.rad(angle))
		)
		
		local params = RaycastParams.new() --dunno what should be here, figure it out

		local ray = workspace:Raycast(orgin.Position, dir*distance, params)

		if not ray then continue end

		if not ray.Instance.Parent:FindFirstChild("Humanoid") then return end

		print("I see player")

	end
end

replace CFrame.lookAt(origin, HumanoidRootPart.Position).LookVector * DISTANCE
with (orgin.Position-HumanoidRootPart.Position).Unit * DISTANCE

CFrame.lookAt(origin.Position, HumanoidRootPart.Position).LookVector

I didnt know origin was a CFrame lol.

CFrame.lookAt is faster than getting the unit of the difference of the two vectors

dam i didnt know that. i just dont like long lines of code XD thx for the info

Same for both, I just benchmarked it lol. It’s only about 0.000001 to 0.000002 seconds faster :sob: