Check If Part Is Behind Character

How would I check if a part is behind my character? I only want it to detect it as behind my character if I have to make a 180 degree turn to walk towards it.

You use the dot product of the position of the part and the character position.

I found this function on the devforums but it is inconsistent.

local function IsBehind(CharHRP,Part)
	local isInfront = false
	local isNextTo = false
	if CharHRP then
		local angle = math.acos(CharHRP.CFrame.LookVector:Dot((Part.Position-(CharHRP.Position-CharHRP.CFrame.LookVector)).Unit))
		isInfront = angle < math.pi/2
		isNextTo = angle < math.pi/1.65
	end
	
	print(CharHRP, Part, isInfront or isNextTo)

	if isInfront or isNextTo then
		return false
	else
		return true
	end
end

yeah thats kinda overcomplicated for what you want

I do it like this:

-- Origin is a BasePart
-- Object is a BasePart or Vector3 (ObjectPosition)
local DistanceToObjectVector3 = (ObjectPosition - Origin.Position)
local ObjectLookVector = Origin.CFrame.LookVector

local IsLookingAt = DistanceToObjectVector3:Dot(ObjectLookVector) > 0


Idk, that doesn’t work with my code. Sometimes it goes backwards and sometimes it errors, or does both.

full code:

local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")

local WalkAnimation = script.Parent:WaitForChild("Humanoid"):WaitForChild("Animator"):LoadAnimation(script.Parent:WaitForChild("Animations"):WaitForChild("WalkAnimation"))

WalkAnimation:Play()

local lastPoint = nil
local lastPoint2 = nil

local ignores = {script.Parent}

for _, part in pairs(workspace.Map:GetDescendants()) do
	if part:IsA("BasePart") and part.Name == "BareGround" then
		table.insert(ignores, part)
	end
end

for _, part in pairs(workspace._MovePoints:GetDescendants()) do
	if part:IsA("BasePart") then
		table.insert(ignores, part)
	end
end

local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = ignores

--task.wait(20)

local function IsBehind(Origin,ObjectPosition)
	local DistanceToObjectVector3 = (ObjectPosition - Origin.Position)
	local ObjectLookVector = -Origin.CFrame.LookVector

	local IsLookingAt = DistanceToObjectVector3:Dot(ObjectLookVector) > 0
	return IsLookingAt
end

while true do
	local possible = workspace._MovePoints:GetChildren()
	if lastPoint ~= nil then
		table.remove(possible, table.find(possible, lastPoint))
	end
	for _, p in pairs(possible) do
		if workspace:Raycast(script.Parent.HumanoidRootPart.Position, (p.Position-script.Parent.HumanoidRootPart.Position), params) ~= nil then
			table.remove(possible, table.find(possible, p))
		end
	end
	local newPoint = possible[math.random(1, #possible)]
	if workspace:Raycast(script.Parent.HumanoidRootPart.Position, (script.Parent.HumanoidRootPart.Position-newPoint.Position), params) ~= nil then
		local dir, lv
		repeat
			task.wait()
			table.remove(possible, table.find(possible, newPoint))
			newPoint = possible[math.random(1, #possible)]
			dir = (Vector3.new(newPoint.Position.X,0,newPoint.Position.Z)-script.Parent:GetPivot().Position).Unit
			lv = Vector3.new(script.Parent:GetPivot().LookVector.X, 0, script.Parent:GetPivot().LookVector.Z)
		until
		workspace:Raycast(script.Parent.HumanoidRootPart.Position, (newPoint.Position-script.Parent.HumanoidRootPart.Position), params) == nil and
			IsBehind(script.Parent.HumanoidRootPart, newPoint.Position) == false
	end
	lastPoint2 = lastPoint
	lastPoint = newPoint
	script.Parent.Humanoid:MoveTo(newPoint.Position)
	script.Parent.Humanoid.MoveToFinished:Wait()
end

the error is on this line, not the code I gave you

Ok so how do you suggest I select a random point for the npc to turn to?