How do I check if a part is facing a player?

I want to check if a specific part is facing the direction of the player

I don’t understand what to try or do, I’ve tried raycasting but that’s not the thing I was looking for.

--Example this is gibberish but
if part is direction of player then
     print("a")
end
1 Like

Dot products might help

4 Likes

You can get the angle between two directions with :Dot().

local v1 = Vector3.new(1, 0, 0) -- Part's LookVector
local v2 = Vector3.new(1, 0, 0) -- Player's LookVector

local Angle = math.acos(v1:Dot(v2)) -- in radians

print(math.deg(Angle)) -- 0

Learn more: The Ultimate Guide to Vector3:Cross() and Vector3:Dot()

3 Likes

When the scalar product of two unit vectors is 1, it means that they are pointing in the same direction. Then you can do the scalar product of the position of the player with respect to the part and the lookvector of the part.

But in practice, it is very difficult for two vectors to point in exactly the same direction, so their scalar product will almost never be 1. To solve this we simply consider a value close to 1.

function partIsDirectionOfPlayer(part, player)
	local character = player.Character
	local head = character and player.Character.Head
	if head then
		local playerDirection = (head.Position - part.Position).unit
		local partDirection = part.CFrame.LookVector.unit
		local coef = playerDirection:Dot(partDirection)
		return coef > 0.95
	end
	return false
end
2 Likes

Using some CFrame magic, I was able to create a small system that achieves this for you.

local startPart = workspace.StartPart
local lookPart = workspace.LookPart

local fieldOfView = 180

function isLookPartInFront()
	local startPartLookVector = startPart.CFrame.LookVector
	local partDifference = (lookPart.CFrame.p - startPart.CFrame.p).Unit
	local value = math.pow((startPartLookVector - partDifference).Magnitude/2, 2)
	if value >= fieldOfView/360 then
		return false
	else
		return true
	end
end

print(isLookPartInFront())

A quick overview of what the variables do and what they’re for:

startPart stores the part that is looking at the other part. In your case, the startPart is the specific part facing in the direction of the player.
lookPart is the part being looked at. This would most likely be a child of the character you’re looking at in your example.
fieldOfView refers to how strict the viewing angle should be (in degrees). A larger value means a larger angle.

The people who replied above me also have some cool ideas that you should check out. I did not even know about the :Dot method, so I will definitely be looking into it.

2 Likes