**|If possible please write easy answers for me to understand when it comes to CFrame math! I'm still figuring out how it works. Thanks in advance.|**

My goal here is to make a building system where I could snap objects to surfaces of other objects while still following a grid (like the Stamper Tool or something else similar.)

Currently I've only managed to make grid snapping (I deleted that part of the code.) Surface snap only works when I remove the grid snapping functionality and all the workarounds I could think of don't work correctly (or I'm probably just tired when I work with them).

What else can I do to make this happen?:

local PlayerCont = game:GetService("Players")
local Mouse = PlayerCont.LocalPlayer:GetMouse()
local PlacementCursor = Instance.new("Part", workspace) -- Since FilteringEnabled is true, we can
-- make the player's cursor invisible to others.
local SnapByStuds = 4

local States = { -- Non functional
	OFF = 0,
	BUILD = 1,
	EDIT = 2,
	COLOR = 3,
	WIRE = 4,
	CLIPBOARD = 5,
	REMOVE = 6
}

local RotationStates -- does nothing for now

-- Initialization

PlacementCursor.Transparency = 0.8 -- 0.8 for now
PlacementCursor.Anchored = true
PlacementCursor.CanCollide = false
PlacementCursor.CastShadow = false
PlacementCursor.Size = Vector3.new(4, 4, 4)
PlacementCursor.Material = "Neon"

Mouse.TargetFilter = PlacementCursor

local cmath = {}

function cmath.even(x, returnNum, custCheck)
	local custN = custCheck or 1
	if returnNum then
		return (x % custN)
	end
	return (x % custN) == 0
end

function cmath.nearest(x, roundnum)
	local rounding = roundnum or 1
	if typeof(x) == "Vector3" then
		local X, Y, Z = x.X, x.Y, x.Z
		local rX, rY, rZ = cmath.even(X, true, rounding) / rounding, cmath.even(Y, true, rounding) / rounding, cmath.even(Z, true, rounding) / rounding
		
		if rX > 0.5 then
			X = math.ceil(X / rounding) * rounding + (SnapByStuds/2)
		else
			X = math.floor(X / rounding) * rounding + (SnapByStuds/2)
		end
		
		if rY > 0.5 then
			Y = math.ceil(Y / rounding) * rounding + (SnapByStuds/2)
		else
			Y = math.floor(Y / rounding) * rounding + (SnapByStuds/2)
		end
		
		if rZ > 0.5 then
			Z = math.ceil(Z / rounding) * rounding + (SnapByStuds/2)
		else
			Z = math.floor(Z / rounding) * rounding + (SnapByStuds/2)
		end
		
		return Vector3.new(X, Y, Z)
	else
		-- numbers only not used for now
	end
end

-- ===========================================================
-- =========================================================== ACTUAL FUNCTIONS
-- ===========================================================

function DisplayNewPosition() -- Something to improve on.
	local Normal = Vector3.FromNormalId(Mouse.TargetSurface)
	local Position = Mouse.Hit.p
	local CursorCFrame = Mouse.Hit
	local Anchor = Mouse.Target
	
	if CursorCFrame ~= nil and Anchor ~= nil then
		local ObjectHit = Anchor.CFrame -- Anchor to center of object + rotation
		local ObjectSpace = Anchor.CFrame:ToObjectSpace(CFrame.new(Position)) * CFrame.Angles(0, 0, 0)
		local ObjectRotation = Anchor.CFrame - Anchor.CFrame.Position
		local RotatedNormal = (ObjectRotation * Normal) * (PlacementCursor.Size / 2)
		--print(RotatedNormal * PlacementCursor.Size)
		local FinalFormulation = (ObjectHit * ObjectSpace) + RotatedNormal
		
		PlacementCursor.CFrame = FinalFormulation
	end
end

function RequestAddition()
	-- nothing yet
end

Mouse.Move:Connect(DisplayNewPosition)

Thanks (again) in advance!