Trying to get a 3D GUIs 2D screen positions

Any idea how to do this please? I tried using AbsolutePosition, but that just gives it in relation to 0,0 position of its SurfaceGui. I also quickly looked into trying to extrapolate it from WorldToScreenPoint, but the math involved in that would be fairly time consuming.

Anyone have any better ideas please?

Just to clarify I have an image label in on a surface GUI, no billboard GUIs

After much toil, I figured out a hacky solution if the cards are aligned on the XAxis (i.e They aren’t rotated and you’re looking straight at 'em)

Excuse the horrible variable naming scheme, I’ve not done this type of maths before and want it to be clear what everything is.

This will create a frame that hovers over the GuiObject Icon.

    local Frame = Instance.new("Frame", _MainUI)
	Frame.Size = UDim2.new(0, 10, 0, 10)
	
	local CardSize = Card.Size
	local CardPxSize = Card.Front.MainFrame.AbsoluteSize
	
	local IconAbsolutePosition = CardIcon.AbsolutePosition
	local IconAbsoluteSize = CardIcon.AbsoluteSize
	
	local XPxToStud = CardPxSize.X / CardSize.X
	local YPxToStud = CardPxSize.Y / CardSize.Y
	
	RunService:BindToRenderStep(GunName .. "CardAppearenceFunction", Enum.RenderPriority.Last.Value, function()
		local MousePosition = Vector2.new(Mouse.X, Mouse.Y)
		local CardPosition = Card.Position
		
		local Vec3CardPosition = Vector3.new(CardPosition.X - (CardSize.X / 2), CardPosition.Y + (CardSize.Y / 2), CardPosition.Z) -- this is the top of the card in studs
		
		local IconPositionOffsetStuds = IconAbsolutePosition.X / XPxToStud

		local Vec3IconPosition = Vec3CardPosition + Vector3.new(IconPositionOffsetStuds, 0, 0)
		
		local IconVec3AbsolutePosition = Camera:WorldToScreenPoint(Vec3IconPosition)
		local IconUDimAbsolutePosition = UDim2.new(0, IconVec3AbsolutePosition.X, 0, IconVec3AbsolutePosition.Y)
		
		local IconTopRightCorner = Camera:WorldToScreenPoint(Vec3IconPosition + Vector3.new((IconAbsoluteSize.X / XPxToStud), 0, 0))
		
		local RealWidth = (IconTopRightCorner - IconVec3AbsolutePosition).X
		Frame.Position = IconUDimAbsolutePosition
	
		Frame.Size = UDim2.new(0, RealWidth, 0, (RealWidth * XPxToStud) / YPxToStud)
	end)

I’d still like a more robust solution if anyone has one.

1 Like

Don’t excuse yourself for writing readable code :wink:

Wouldn’t it be better just to have a 2D GUI and set its position to :WorldToScreenPoint(Adornee.Position)?

Sorry to be picky, but you should get used to parenting the object, outside of the Instance function.

You can see the little ā€˜line through’ on this wiki page.

1 Like

Ya I do that for performance intensive tasks (say a new obj every frame), but I’m often just lazy. Looks neater.

As for what Emerald wrote, hat would probably work, however I’d need to set up 4 adornees, I think this solution is probably easier and tidier.

Thanks for your input!