Help with Snap to Grid

Hey, I’m trying to make a game inspired by Blockate and had to make a placement system, before you tell me that there is alot of snap to grid resources here in devforum, I’d like to say that mine is different.

So I have those two functions to serialize and deserialize the block’s position:

-- Serialize
local function GetInfo(Axis, Size)
	local Indicator = ""
	
	if Axis % 4 - 4 == -2 and Size == 1 then
		Indicator = "=-2"
	elseif Axis % 4 - 4 == -1 and Size == 1 then
		Indicator = "=-1"
	elseif Axis % 4 - 4 == -3 and Size == 1 then
		Indicator = "=2"
	elseif Axis % 4 - 4 == -4 and Size == 1 then
		Indicator = "=1"
	elseif Axis % 4 - 4 == -2 and Size == 2 then
		Indicator = "=-1"
	elseif Axis % 4 == 0 then
		Indicator = ""
	elseif Axis % 4 == 2 and Size == 2 then
		Indicator = "=1"
	else
		return "Invalid Position"
	end
	
	return math.floor(Axis / 4 + 0.5)..Indicator
end

-- Deserialize
function Deserialize:Position(String, Size)
	local Position = string.split(String, " / ")[1]
	local Axes = string.split(Position, ", ")
	
	local NewPosition = Vector3.zero
	
	for Index, Axis in ipairs(Axes) do
		local Splitted = string.split(Axis, "=")
		
		if Splitted[2] then
			if Splitted[1] ~= "Invalid Position" then
				NewPosition = Vector3.new(
					Index == 1 and ((tonumber(Splitted[1]) * 4) + (tonumber(Splitted[2]) > 0 and Size.X or -Size.X) / 2 + Size.X * (tonumber(Splitted[2]) > 0 and tonumber(Splitted[2]) - 1 or tonumber(Splitted[2]) + 1)) or NewPosition.X,
					Index == 2 and ((tonumber(Splitted[1]) * 4) + (tonumber(Splitted[2]) > 0 and Size.Y or -Size.Y) / 2 + Size.Y * (tonumber(Splitted[2]) > 0 and tonumber(Splitted[2]) - 1 or tonumber(Splitted[2]) + 1)) or NewPosition.Y,
					Index == 3 and ((tonumber(Splitted[1]) * 4) + (tonumber(Splitted[2]) > 0 and Size.Z or -Size.Z) / 2 + Size.Z * (tonumber(Splitted[2]) > 0 and tonumber(Splitted[2]) - 1 or tonumber(Splitted[2]) + 1)) or NewPosition.Z
				)
			else
				return "Invalid Position"
			end
		else
			if Splitted[1] ~= "Invalid Position" then
				NewPosition = Vector3.new(
					Index == 1 and tonumber(Splitted[1]) * 4 or NewPosition.X,
					Index == 2 and tonumber(Splitted[1]) * 4 or NewPosition.Y,
					Index == 3 and tonumber(Splitted[1]) * 4 or NewPosition.Z
				)
			else
				return "Invalid Position"
			end
		end
	end
	
	return NewPosition
end

It works fine with 4x4x4 blocks, but I want my game to have 2x2x2, 1x1x1 blocks and some other sizes.
I know that I could just change the Serialize function to return Axis / Size instead of Axis / 4 but that would make the snap to grid to not be aligned to other block sizes

This is how I calculate the snap to grid:

local Target = Result.Position + Result.Normal * 1.5

Block.Position = Vector3.new(
	math.floor(Target.X / Block.Size.X + 0.5) * Block.Size.X,
	math.floor(Target.Y / Block.Size.Y + 0.5) * Block.Size.Y,
	math.floor(Target.Z / Block.Size.Z + 0.5) * Block.Size.Z
)

Just the preview is placed in the wrong position, but the placed blocks goes to the right position.
I want help converting it to the serialize script without the block being offsetted from the mouse position

Sorry for bumping but I really need help with this