Function all glitched when testing it on mobile (ScreenGui and SurfaceGui)

I am Trying to make a place system for my card game, when you drag a card on top of another card, it replaces the old card. I had to use functions that transform 3D positions in 2D positions. It works, but not on mobile, where every position is messed up as you see in the output.
The field is divided in: FrontDXRearguard (Front right), FrontSXRearguard (front left), Vanguard (Front Center), BackDXRearguard and so on. Look at the output to see where the card position the function think is at.

A possible issue could be how the position is scaled?

local module = {}

task.wait(1) --Per far caricare gli oggetti nel workspace

local workSpace = game:GetService("Workspace")

local playerFields = workspace:WaitForChild("PlayerFields")
local cardsInField = playerFields:WaitForChild("CardsInField1")
local partsOfTheField = cardsInField:GetChildren()
local validImages = {} -- Tabella per memorizzare tutte le immagini valide
local draggingImage = nil -- L'immagine che stai trascinando
local dragging = false -- Stato del drag
local overlappingImage = nil -- L'immagine sopra cui la carta è trascinata
local camera = workspace.CurrentCamera

local function get2DPosition(surfaceGuiImage)
	local part = surfaceGuiImage.Parent -- Il BasePart su cui è montato il SurfaceGui
	if not part then
		return nil
	end

	local position3D = part.Position
	local screenPos, onScreen = camera:WorldToScreenPoint(position3D)

	if onScreen then
		local size = surfaceGuiImage.AbsoluteSize
		return {
			Position = Vector2.new(screenPos.X, screenPos.Y),
			Size = Vector2.new(size.X, size.Y)
		}
	else
		return nil
	end
end

-- Inizializza le immagini valide
for _, part in ipairs(partsOfTheField) do
	for _, gui in ipairs(part:GetChildren()) do
		if gui:IsA("SurfaceGui") and gui.Name == "FrontCardGui" then
			local image = gui:WaitForChild("CardImage")
			if image and image:IsA("ImageLabel") then
				table.insert(validImages, image)
			end
		end
	end
end

local function isOverlapping(dragImage, surfaceGuiImage)
	local dragPos = dragImage.AbsolutePosition
	local dragSize = dragImage.AbsoluteSize

	-- Calcola il centro della carta draggata
	local dragCenter = dragPos + dragSize / 2

	-- Calcola l'area valida (metà delle dimensioni della carta, centrata sul centro)
	local validAreaSize = dragSize / 2
	local validAreaLeft = dragCenter.X - validAreaSize.X / 2
	local validAreaRight = dragCenter.X + validAreaSize.X / 2
	local validAreaTop = dragCenter.Y - validAreaSize.Y / 2
	local validAreaBottom = dragCenter.Y + validAreaSize.Y / 2

	-- Ottieni i dati della posizione 2D del target
	local surfaceData = get2DPosition(surfaceGuiImage.Parent)

	if not surfaceData then
		return false -- Se il target non è visibile, non può esserci sovrapposizione
	end

	local targetPos = surfaceData.Position
	local targetSize = surfaceData.Size

	-- Verifica se l'area valida della carta si sovrappone al rettangolo del target
	return validAreaRight >= targetPos.X and validAreaLeft <= targetPos.X + targetSize.X
		and validAreaBottom >= targetPos.Y and validAreaTop <= targetPos.Y + targetSize.Y
end




-- Funzione per iniziare il drag
function module.startDragging(image)
	print("called startDrag")
	dragging = true
	draggingImage = image
end

-- Funzione per fermare il drag
function module.stopDragging()
	print("Called endDrag")
	if dragging then
		dragging = false

		-- Se l'immagine è sopra una valida, aggiorna il target
		if overlappingImage and draggingImage then
			print(overlappingImage.Parent.Parent)
			overlappingImage.Image = draggingImage.Image
			draggingImage.Position = UDim2.new(0, 0, 0, 0) -- Reset della posizione
			draggingImage.Visible = false -- Nasconde l'immagine trascinata (opzionale)
		end

		draggingImage = nil
		overlappingImage = nil -- Resetta lo stato di sovrapposizione
	end
end

-- Controllo continuo durante il drag
local function updateDragging()
	if dragging and draggingImage then

		overlappingImage = nil -- Resetta l'immagine sovrapposta
		
		-- Controlla tutte le immagini valide
		for _, image in ipairs(validImages) do
			
			if isOverlapping(draggingImage, image) then
				
				overlappingImage = image -- Memorizza l'immagine target sopra cui si trova
				print(overlappingImage.Parent.Parent)
				break
			end
		end
	end
end


-- Controllo continuo durante il drag
game:GetService("RunService").RenderStepped:Connect(updateDragging)

return module

PC: Works

External Media

Mobile:

External Media