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?