How to get a 3D position from a 2D map?

I’m trying to generate a position in the workspace by clicking on a map frame.
I use Player:GetMouse().X and Player:GetMouse().Y to get the mouse position.
This function converts a 3D position in the workspace to a 2D position on the frame:

local function Position3dTo2d(position, center)
	local x, y, z = position.X - center.X, position.Y, position.Z - center.Z
	local X, Y = Frame.AbsoluteSize.X * x / ZoomDistance + Frame.AbsoluteSize.X/2, GUI.AbsoluteSize.Y * z / ZoomDistance + Frame.AbsoluteSize.Y/2
	
	return Vector2.new(X, Y)
end

This function converts a 2D position to a 3D position:

local function Position2dto3d(x, y)
	local X = (x - Frame.AbsoluteSize.X/2) * ZoomDistance / Frame.AbsoluteSize.X
	local Z = (y - Frame.AbsoluteSize.Y/2) * ZoomDistance / Frame.AbsoluteSize.Y
	
	return Vector3.new(X + Center.X, 0, Z + Center.Z)
end

The position generated is only correct on the X-axis, not the Z-axis. I believe that this is related to the screen’s resolution. The offset on the Z-axis changes as the screen size changes. How can I fix this? :thinking:

Any help is greatly appreciated! :star_struck:

Is Camera:WorldToScreenPoint what you want instead?

1 Like

Oops, I got it the other way around. You might want Camera:ScreenPointToRay (or ViewportPointToRay if you find the GUI offset hurts you).

Have you tried using UIAspectRatioConstraint?

I’m not entirely sure if the map you’re describing is a static-sized interactable frame, but the frame’s absolute size is different for every resolution… (assuming you’re using scale, and not offset)

Also, try this…
Again, I don’t know if the map’s size is static, but try using Frame.Size.Scale (or offset if applicable) instead of AbsoluteSize.

If you believe it to be the inset you can try using this to correct for it

game:GetService("GuiService"):GetGuiInset()

Or you could try setting this:

1 Like

Thank you! That did the trick :grinning:

Heres the modified function:

local function Position2dto3d(x, y)
	local inset = GuiService:GetGuiInset().Y
	
	local X = (x - Frame.AbsoluteSize.X/2) * ZoomDistance / Frame.AbsoluteSize.X
	local Z = (y - Frame.AbsoluteSize.Y/2 + inset) * ZoomDistance / Frame.AbsoluteSize.Y + inset
	
	return Vector3.new(X + Center.X, 0, Z + Center.Z)
end

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.