Object not facing / aligning correctly

I am making a game like SprayPaint, where you have your own spray paint can tool, and you paint with cylinders, which are being placed. I have came far with the spraying mechanic, though I ran into an issue. When i spray on walls, it aligns perfectly with the walls surface I’m spraying on. The issue is, on flat surfaces or angled surfaces, It doesn’t align correctly. The paint is a cylinder which has the edge and the face. I want it to align with the face but it aligns on flat or angled surfaces with the edge.

I have tried:

  • Searching through the Roblox DevForum for answers
  • Playing around with stuff
  • Asking ChatGPT for fixes

I want the paint’s face to align with every type of angle or surface

local sprayEvent = game.ReplicatedStorage.spray
local range = 2

function alignPaint(paint, res, layer)
    local surfaceNormal = res.Normal
    local hitPosition = res.Position
    local upVector = Vector3.new(0, 1, 0)

    local rotation = CFrame.lookAt(Vector3.new(), surfaceNormal):inverse() * CFrame.lookAt(Vector3.new(), upVector)
    if math.abs(surfaceNormal.Y) > 0.95 then
        rotation = CFrame.Angles(math.pi / 2, 0, 0)
    end
    
    paint.CFrame = CFrame.new(hitPosition) * rotation * CFrame.new(0, layer, 0)
end


sprayEvent.OnServerEvent:Connect(function(client, MousePos, transparency, size, layer, colorR, colorG, colorB)
	local can = client.Character:FindFirstChildOfClass("Tool")	
	if can == nil then return end
	
	local dir = (MousePos - can.Handle.Position) * range
	
	local rayParams = RaycastParams.new()
	rayParams.FilterDescendantsInstances = {client.Character}
	rayParams.FilterType = Enum.RaycastFilterType.Exclude
	
	local res = workspace:Raycast(can.Handle.Position, dir, rayParams)
	
	if res == nil then return end
	
	local paint = game.ReplicatedStorage.Paint:Clone()
	paint.Name = client.Name
	paint.Parent = game.Workspace.PaintStorage
	paint.Transparency = transparency
	paint.Position = MousePos
	paint.Position += Vector3.new(0, layer, 0)
	paint.Size = Vector3.new(.001, size, size)
	paint.Color = Color3.new(colorR, colorG, colorB)
	
	alignPaint(paint, res, layer)
end)

I’m looking forward to hear from help!

Update: I later found it in the DevForum still (I was probably blind before).

I added this:

paint.CFrame = CFrame.new(MousePos, MousePos + res.Normal) * CFrame.Angles(0, math.pi/2, 0)

and it works perfectly!
:slight_smile: