Raycasting returning nil when there is no reason it should

I was trying to create an NPC that utilizes raycasts to detect the presence of a player. However, the raycasts seem not to register, except at certain angles and distances.

robloxapp-20230719-1113405.wmv (1.3 MB)

Relevant snippet:

local function lookForPlayer()
--Character is the NPC, not the player
	local Players = game.Players:GetPlayers()
	for i, Player in pairs(Players) do
		if Player.Character then
			local RaycastParameters = RaycastParams.new()
		--	RaycastParameters.FilterType = Enum.RaycastFilterType.Exclude
		--	RaycastParameters.FilterDescendantsInstances = {character}
			
			local Raycast = workspace:Raycast(character.Head.Position,Player.Character.Head.Position,RaycastParameters)
			if Raycast then
				local RigHeadPos = character.Head.Position
				local PlrHeadPos = Player.Character.Head.Position
				print(math.deg(math.atan2(PlrHeadPos.Y-RigHeadPos.Y,PlrHeadPos.X-RigHeadPos.X))-character.Head.Orientation.Y)
				character.Head.Color = Color3.new(1,0,0)
			else
				character.Head.Color = Color3.new(0,0,0)
			end			
		end
	end
end
game["Run Service"].Heartbeat:Connect(lookForPlayer)

There should be raycasts registering whenever ANYTHING is hit, (which is why I disabled the exclusion checks), but still it returns nil.

The second argument in workspace:Raycast() is a direction vector from the first argument, not a target position. All you need to do is subtract your start position from your target position to get the direction vector, like this:

local function lookForPlayer()
	--Character is the NPC, not the player
	local Players = game.Players:GetPlayers()
	for i, Player in pairs(Players) do
		if Player.Character then
			local RaycastParameters = RaycastParams.new()
			--	RaycastParameters.FilterType = Enum.RaycastFilterType.Exclude
			--	RaycastParameters.FilterDescendantsInstances = {character}
			
			local RigHeadPos = character.Head.Position
			local PlrHeadPos = Player.Character.Head.Position
			
			local Raycast = workspace:Raycast(RigHeadPos, PlrHeadPos - RigHeadPos, RaycastParameters)
			
			if Raycast then
				print(math.deg(math.atan2(PlrHeadPos.Y-RigHeadPos.Y,PlrHeadPos.X-RigHeadPos.X))-character.Head.Orientation.Y)
				character.Head.Color = Color3.new(1,0,0)
			else
				character.Head.Color = Color3.new(0,0,0)
			end			
		end
	end
end
game["Run Service"].Heartbeat:Connect(lookForPlayer)
2 Likes

That’s not everything. You should also define the distance the ray should travel, and use .Unit, here is an example:

(PlrHeadPos - RigHeadPos).Unit * 500 -- replace 500 with your distance

.Unit converts the direction into a number with a magnitude of 1, and the * 500 determines your range

If we assume the OP is trying to cast from a head to another head, then actually yes, that is everything. You’re using the displacement between two heads as the direction for the raycast. But you should definitely increase that vector by just a bit for tolerance purposes. Normalizing the direction shouldn’t be necessary

workspace:Raycast(origin, (destination - origin)*1.1, RCP) --the 1.1 is for tolerance

You mean a vector :slightly_smiling_face:

1 Like

That’s true, but either option works. In his case, if he wants to detect how far the player is from the NPC, he can use your option or mine. If he uses my option, the raycast should return nil or some object not equal to the NPC if the player isn’t close enough to the NPC

And it’s both a vector and a direction

I was talking about number, you said that Unit converts the direction into a number

Oh, you’re right then. My bad

(character limit)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.