Get the alpha of how much two characters are looking at each other

local function GetLookingAtAlpha(objA: Model | BasePart, objB: Model | BasePart, includeYAxis: boolean?): number
	local aCF = objA:GetPivot()
	local aPos, bPos = aCF.Position, objB:GetPivot().Position

	if not includeYAxis then
		local noHeightMultiplier = Vector3.new(1, 0, 1)

		aPos, bPos = aPos*noHeightMultiplier, bPos*noHeightMultiplier
	end

	local toB = (bPos - aPos).Unit

	local deltaDeg = math.deg(math.acos(toB:Dot(aCF.LookVector)))

	return (180 - deltaDeg) / 180
end

local function GetLookingAtEachOtherAlpha(objA: Model | BasePart, objB: Model | BasePart, includeYAxis: boolean?): number
	local aCF, bCF = objA:GetPivot(), objB:GetPivot()
	local aPos, bPos = aCF.Position, bCF.Position
	
	local noHeightMultiplier = Vector3.new(1, 0, 1)
	
	if not includeYAxis then
		local noHeightMultiplier = Vector3.new(1, 0, 1)

		aPos, bPos = aPos*noHeightMultiplier, bPos*noHeightMultiplier
	end
	
	local toB, toA = (bPos - aPos).Unit, (aPos - bPos).Unit
	
	local aDeltaDeg = math.deg(math.acos(toB:Dot(aCF.LookVector)))
	local bDeltaDeg = math.deg(math.acos(toA:Dot(bCF.LookVector)))
	
	local totalDeltaDeg = aDeltaDeg + bDeltaDeg
	
	return (360 - totalDeltaDeg) / 360
end
13 Likes

This solution I just thought of seemed to work for me. :slight_smile:

local function lookAtAlpha(a: CFrame, b: CFrame): number
    return -a.LookVector:Dot((a.Position - b.Position).Unit)
end
3 Likes

I think you meant to write a.Position - b.Position.

The alpha range produced by your function is from [-1, 1] instead of (0, 1), which isn’t a major hurdle but is inconvenient. Also if one CFrame is higher than the other it might produce unexpected results (if one character is taller than the other, which is why I have includeYAxis). Using CFrames instead of parts or models is just a matter of opinion. I will probably add support for inputting CFrame values as well (these started as functions for a ModelUtil module).

Your solution is elegant, but due to the y axis potentionally throwing off results and the range going into the negatives I would still prefer mine.

Ah I thought -1 was preferable due to someone being able to tell if it was looking away by the sign alone and not checking < 0.5 (I know you said alpha but to me -1 to 1 made more contextual sense). I didn’t really do any Y axis testing and I can definitely do that but from what I did test it worked exactly as I expected it to.

1 Like

If you do want between 0 and 1

local function lookAtAlpha(a: CFrame, b: CFrame): number
    return -a.LookVector:Dot((a.Position - b.Position).Unit) * 0.5 + 0.5
end

Again, from testing by moving the target along the Y axis, the code works exactly as expected. All it does is look for the difference between -a.LookVector and a projected vector between a and b.

1 Like

It’s not working exactly as expected for me…

When adding a greater difference in height the lookAtAlpha() returns a smaller number making a smaller amount of red.

That’s the expected behaviour, my code does not ignore the relative Y difference.

Ahh I see. I was saying that it might be unexpected by the end user if that wasn’t accounted for.