I am currently working on a small project which is a Minecraft like game and I am using raycast to detect the face that the player is clicking but it seems to only work when it’s close. It works out of first person pretty much all the time however when I go in first person, it seems to not work correctly.
It usually is offset and on the incorrect face (Example: 9 studs away and look at a part from the top says the face is on the right or front)
I have the raycast code and surface detecting code listed below:
local length = 15 --Reach distance
function getRayCollisionNormal(x,y)
local cam = workspace.CurrentCamera
local viewportPoint = cam.ViewportSize / 2
local unitRay = cam:ViewportPointToRay(viewportPoint.X, viewportPoint.Y, 0)
local rayResult = workspace:Raycast(unitRay.Origin, unitRay.Direction * length)
if (rayResult) then
local instance = rayResult.Instance
local normal = rayResult.Normal
-- Get an object-space normal for rotated instance
if (instance) then
normal = rayResult.Normal
end
return normal or nil;
end
end
function GetFaceOfPart()
local camera = workspace.CurrentCamera
local hitNormal = getRayCollisionNormal(PlayerMouse.X, PlayerMouse.Y)
local surface = nil;
if (hitNormal) then
local dotY = hitNormal:Dot(Vector3.new(0,1,0))
local dotX = hitNormal:Dot(Vector3.new(1,0,0))
local dotZ = hitNormal:Dot(Vector3.new(0,0,1))
if math.round((math.abs(dotY))) >= 0.9 then
if math.round((dotY)) < 0 then
surface = Enum.NormalId.Bottom
else
surface = Enum.NormalId.Top
end
elseif math.round((math.abs(dotX))) >= 0.9 then
if math.round((dotX)) < 0 then
surface = Enum.NormalId.Left
else
surface = Enum.NormalId.Right
end
else
if math.round((dotZ)) < 0 then
surface = Enum.NormalId.Front
else
surface = Enum.NormalId.Back
end
end
end
print(surface.Name)
return surface
end
Much thanks to anybody that can help!