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

0

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.

0

Otherwise you could use the position at the end of the ray and find the closest face from that.

0

how would I set the orientation of the invisible part, to make sure it matches the face of the object ?