Correcting a Billboard UI That is Going Off-Screen

In a 2D top-down game, sometimes a southern door is close to the bottom of the screen. When the ‘Open Door’ options dialogue appears (in a Billboard GUI), it is sometimes half off screen. I’ve been trying to correct it, but, the numbers don’t add up.

The billboard is at the bottom, and is missing its ‘description’ textbox; if there were multiple unlock options, then, they also go off-screen. The total thing varies in size according to the options. It’s not always at the bottom, so, I can’t implement a generic top adjustment of -50 etc (else it starts appearing over the middle the map in many rooms).

image

I have some test code to print the Y-values of the Billboard and screen size, using some ideas seen on this forum.

Local Script, a direct child of the BB:

-- Now it is displayed, check to see if it going off-screen (for now, just checking top-or-bottom)
-- bb is the BillboardGUI, created just beforehand, parented & with some sizing tweaks.
print(bb.AbsolutePosition.Y.."+"..bb.AbsoluteSize.Y.."+10="..(bb.AbsolutePosition.Y + bb.AbsoluteSize.Y + 10),"is it >",workspace.CurrentCamera.ViewportSize.Y)
if (bb.AbsolutePosition.Y + bb.AbsoluteSize.Y + 10) > workspace.CurrentCamera.ViewportSize.Y then
	bb.SizeOffset.Y = workspace.CurrentCamera.ViewportSize.Y - bb.AbsolutePosition.Y - bb.AbsoluteSize.Y - 10
end

This prints:

0+60+10=70 is it > 470

If the total of those numbers is > 470, then, it is off-screen. It IS off-screen, but the numbers don’t reflect that, and so it never fires the correction script.

Why does bb.AbsolutePosition.Y say ‘0’? Selecting the BB in the studio tree shows its boundaries; it definitely starts along its top border as you’d expect, so definitely has a HIGH absolute-Y; it must be around 410.

Have I got the entire Y-axis upside-down? If 0 is at the bottom… I need to check that the added-up heights are LESS than the top-value. I’ll test.

[Edit: Ah can’t be that, else the first “0” value would be about 50 or 60 or something (‘0’ doesn’t make sense, as the top is on-screen). And the total height would have to be around 120.]

Can you tell me where is the Billboard Gui parented?

Correct me if i’m wrong but if the BillboardGUI is parented to the workspace I think it will always return 0,0 since it is positioned in a 3d space (workspace) and not in a 2d space (UI).

ScreenGUI; it gets Adornee when required/wanted, to any object that generates a multiple-choice for the user.

image

1 Like

I am not 100% sure but I think BillboardGui always return 0,0 absolute position.

You can get around this by using Camera:WorldToViewportPoint() to get the coordenates of the center of the Billboard and calculate the absolute position from there.

1 Like

I can’t see how to get a Vector3 to give to Camera:WorldToViewportPoint() or to give to the similar-looking :WorldToScreenPoint , the BB GUI element doesn’t have any CFrame3 or Vector3 properties, should I be creating Vector3.new(X,Y,Z)… given the lack of .AbsolutePosition on the BB GUI, how would I get sensible X,Y values? (And presumably I’d just put something ‘random’ as the Z, like 0, or 10, or 100).

The Billboard Gui needs to have a part as an adornee, use the parts position as the vector3. (And if you have an offset on the bb position just add that to the parts position)

[edit: I will try to record what I’m trying to explain in case you still don’t get it]

1 Like

From my testing this worked just fine:

local function GetBillboardAbsolutePosition(bb)
	local vec3 = workspace.CurrentCamera:WorldToViewportPoint(bb.Adornee.Position)
	return Vector2.new(vec3.X, vec3.Y) - bb.AbsoluteSize/2
end

Now to get the absolute position of the billboard just use GetBillboardAbsolutePosition() and use the billboard as the argument.
Let me know if there are any more issues!

1 Like

Ah, yeah, use the Adornee part’s physical location. But actually… if I do that… because I have a top-down camera, I could probably just use that CFrame to calculate if the GUI goes off-screen without using WorldToViewportPoint. I.e., CFrame.Y + GUI heights > Camera.Viewport.Y

I’ll do some testing, will probably mark you as Correct Answer regardless, thanks.

The next round of problems was with applying an offset to get the BB back onto screen; ExtentsOffset (and the other similar one) use /2 dimension fractions, and everytime I thought I’d worked out to to use them to ‘move up 60 pixels’, they’d just go do completely random whole-screen moves.

So in the interest of time, I scrapped the whole idea of using Billboards, and just switched to a simple ScreenGUI Frame with a bit of autosizing, and a position of:

lBBUI.Position= UDim2.new(0.5,-(lBBUI.AbsoluteSize.X/2),0.5,-(lBBUI.AbsoluteSize.Y/2))