Possible applications : bullet holes in walls/ parts, melee weapon marks, blood spills on walls. If I get this part right, it should be easy to attach a GUI with an ImageLabel on the clicked face, at the approximate position of the mouse hit.
The following code goes inside a LocalScript. Problem is, it only gives the right answer part of the time (about half of the time it returns the wrong face). How can I make it more accurate, please ? Thank you.
local Player = game.Players.LocalPlayer
local mouse = Player:GetMouse()
for i = 1, 20 do -- generating 20 random parts
local part = Instance.new("Part", game.Workspace)
part.Name = 'random part'
part.Anchored = true
part.Size = Vector3.new(math.random(1, 20), math.random(1, 10), math.random(1, 20))
part.Position = Vector3.new(math.random(-50, 50), 5, math.random(-50, 50))
part.BrickColor = BrickColor.Random()
end
mouse.Button1Down:Connect(function()
if mouse.Target then
local hitPos = mouse.Hit.p
local hit = mouse.Target -- object that was clicked on
local sides = {}
local sizes = Vector3.new(hit.Size.X,hit.Size.Y,hit.Size.Z)
local pos = hit.Position -- [vector3 of] position of the object that was clicked
sides[1] = pos + hit.CFrame:VectorToWorldSpace(Vector3.new(0,0,-hit.Size.Z/2)) --front
sides[2] = pos + hit.CFrame:VectorToWorldSpace(Vector3.new(0,0,hit.Size.Z/2)) --back
sides[3] = pos + hit.CFrame:VectorToWorldSpace(Vector3.new(hit.Size.X/2,0,0)) --right
sides[4] = pos + hit.CFrame:VectorToWorldSpace(Vector3.new(-hit.Size.X/2,0,0)) --left
sides[5] = pos + hit.CFrame:VectorToWorldSpace(Vector3.new(0,hit.Size.Y/2,0)) --top
sides[6] = pos + hit.CFrame:VectorToWorldSpace(Vector3.new(0,-hit.Size.Y/2,0)) --bottom
local ClosestSide = 1
for i,v in ipairs (sides) do
if (hitPos - v).Magnitude < (hitPos - sides[ClosestSide]).Magnitude then
ClosestSide = i
end
end
print ('ClosestSide is : '.. tostring(ClosestSide))
if ClosestSide == 1 then print("front")
elseif ClosestSide == 2 then print("back")
elseif ClosestSide == 3 then print("right")
elseif ClosestSide == 4 then print("left")
elseif ClosestSide == 5 then print("top")
elseif ClosestSide == 6 then print("bottom")
end
end
end)

3 comments
Why not send over the position of the end of your ray from the server, then create a bullet hole on an invisible part at the position, and all you'll have to do is make sure the orientation is correct.
Otherwise you could use the position at the end of the ray and find the closest face from that.
how would I set the orientation of the invisible part, to make sure it matches the face of the object ?