I want to get the face of the part the player is facing with a raycast if that’s possible. I’m trying to make a ledge climbing system where the player would jump and climb edges.
I have heard about face normal with raycasting but don’t know how I could use that to help me get the actual face(to then get the edges)
Here is the code I have right now
Remotes.TestFunction.OnClientInvoke = function(part,normal)
print("[PLAYER IS CLIMBING]")
warn(part)
local topSurface = part.CFrame * CFrame.new(0,(part.Size.Y/2),0) -- gets the top face of the part
local edges = {} -- table for storing corners position and how far the edge is from the player
-- corners positions
local leftEdge1 = topSurface * CFrame.new((part.Size.X/-2),(part.Size.Y/2),(part.Size.Z/-2))
local leftEdge2 = topSurface * CFrame.new((part.Size.X/-2),(part.Size.Y/2),(part.Size.Z/2))
local rightEdge1 = topSurface * CFrame.new((part.Size.X/2),(part.Size.Y/2),(part.Size.Z/-2))
local rightEdge2 = topSurface * CFrame.new((part.Size.X/2),(part.Size.Y/2),(part.Size.Z/2))
-- distance between corner and player
local distanceFromleftEdge1 = (leftEdge1.Position - self.Char.HumanoidRootPart.CFrame.Position).Magnitude
local distanceFromleftEdge2 = (leftEdge2.Position - self.Char.HumanoidRootPart.CFrame.Position).Magnitude
local distanceFromrightEdge1 = (rightEdge1.Position - self.Char.HumanoidRootPart.CFrame.Position).Magnitude
local distanceFromrightEdge2 = (rightEdge2.Position - self.Char.HumanoidRootPart.CFrame.Position).Magnitude
edges[1] = {distanceFromleftEdge1,leftEdge1}
edges[2] = {distanceFromleftEdge2,leftEdge2}
edges[3] = {distanceFromrightEdge1,rightEdge1}
edges[4] = {distanceFromrightEdge2,rightEdge2}
print(edges)
table.sort(edges, function(a,b) -- sort by distance. smallest first and biggest last.
return a[1] < b[1]
end)
local edge1 = edges[1]
local edge2 = edges[2]
local distanceBettweenCorners = (edge2[2].Position - edge1[2].Position).Magnitude -- making the edge from two corners
local inBettween = edge1[2]:Lerp(edge2[2], (edge1[1]/distanceBettweenCorners)) -- getting the player distance and putting the player on the edge
self.Char.PrimaryPart.CFrame = inBettween -- putting the player on the edge
end
I’m trying to figure out how to get the exact face of a part the player is facing. Any assistance would be greatly appreciated.
I don’t know much about raycasting, but assuming the part is a block then all 6 faces have their own normal, can’t you just map those normals to faces?
Getting the corners of a face is a bit more messy since you would need to know which Axis to use maths on, i’m lazy so i don’t know any easy way but i would just code 6 different axis calculations to get the corner of any face.
this is the image i always refer to whenever i need to get the corners of a basepart.
local function GetEnumNormalFromRay(ray :RaycastResult)
local part = ray.Instance
local Position = ray.Position
local Normal = {
[1] = {Position = part.CFrame * CFrame.new(0,0,-part.Size.Z/2),EnumNormal = Enum.NormalId.Front},
[2] = {Position = part.CFrame * CFrame.new(0,part.Size.Y/2,0),EnumNormal = Enum.NormalId.Back},
[3] = {Position = part.CFrame * CFrame.new(0,part.Size.Y/2,0),EnumNormal = Enum.NormalId.Top},
[4] = {Position = part.CFrame * CFrame.new(0,-part.Size.Y/2,0),EnumNormal = Enum.NormalId.Bottom},
[5] = {Position = part.CFrame * CFrame.new(part.Size.X/2,0,0),EnumNormal = Enum.NormalId.Right},
[6] = {Position = part.CFrame * CFrame.new(-part.Size.X/2,0,0),EnumNormal = Enum.NormalId.Left},
}
local Closest = Normal[1]
for _,Side in pairs(Normal) do
Side.Position = Side.Position.Position
local lookForward = Vector3.fromNormalId(Side.EnumNormal)
local lookToPoint = (Side.Position - Position).unit
local angle = math.deg(math.acos(math.clamp(lookForward:Dot(lookToPoint), -1, 1)))
if (Side.Position - Position).magnitude < (Closest.Position - Position).magnitude then
if angle < 90 then
Closest = Side
end
end
end
return Closest.EnumNormal
end
local ray = workspace:Raycast(Vector3.new(1,10,0),Vector3.new(0,-15,0))
print(GetEnumNormalFromRay(ray))