Roblox guide: 3d GUI!

Are you able to send over the code? Would be useful for something I’m making
the one from the second video

local function MenuAnimation(Delta)
	-- // Variables
	local Viewport = Camera.ViewportSize
	local Ratio = Viewport.X/Viewport.Y
	local PixelPerStud -- This is set lower down
	local MouseLocation = not UserInputService.MouseEnabled and Vector2.zero or Vector2.new((Mouse.X/ScreenGui.AbsoluteSize.X)*2-1,((Mouse.Y+36)/ScreenGui.AbsoluteSize.Y)*2-1)

	-- // Raycasting
	local TopLeft = Camera:ViewportPointToRay(PADDING,PADDING,DEPTH)
	local TopLeftPos = (TopLeft.Origin+TopLeft.Direction)
	local BottomRight = Camera:ViewportPointToRay(Viewport.X-PADDING,Viewport.Y-PADDING,DEPTH)
	local BottomRightPos = (BottomRight.Origin+BottomRight.Direction)

	-- // Math
	local Diagonal = (TopLeftPos-BottomRightPos).Magnitude
	local Y = math.sqrt((Diagonal^2)/(Ratio^2+1))
	local X = math.sqrt(Diagonal^2 - Y^2)
	local Size = Vector2.new(X,Y)

	PixelPerStud = Viewport.X/Size.X

	-- // Background
	local XSize = Y*BackgroundSettings.Ratio

	local Wobble = Vector2.new(math.clamp(Mapping(MouseLocation.X,-1,1,-1,1/((XSize/2+(PADDING*2)/PixelPerStud)/Size.X)),-1,1),MouseLocation.Y)*MAX_WOBBLE

	Background.CFrame = (CFrame.new((TopLeftPos+BottomRightPos)/2+Vector3.new(Size.X*(NoticeTween.Value),0,0)) * Camera.CFrame.Rotation)*CFrame.new(-Size.X/2 + XSize/2,0,-PART_DEPTH/2) * CFrame.Angles(-Wobble.Y*(1-math.abs(Wobble.X/MAX_WOBBLE)),Wobble.X + MAX_WOBBLE/4,0)
	Background.Size = Vector3.new(XSize,Size.Y,PART_DEPTH)

	local ButtonSize = ((Size.Y*(1-BackgroundSettings.Header))-((BUTTON_PADDING/PixelPerStud)*(#BackgroundButtons+1)))/#BackgroundButtons

	for i = #BackgroundButtons, 1, -1 do  
		local v = BackgroundButtons[i]
		local mi = #BackgroundButtons - i -- Modified index, for messing with the position

		v.Size = Vector3.new(XSize-(BUTTON_PADDING*2)/PixelPerStud,ButtonSize,PART_DEPTH/2)
		v.CFrame = Background.CFrame * CFrame.new(0,-Background.Size.Y/2+v.Size.Y/2+BUTTON_PADDING/PixelPerStud +(ButtonSize+BUTTON_PADDING/PixelPerStud)*mi,PART_DEPTH/4+(PART_DEPTH/2)*((1-v.Tween.Value)*0.3)+0.1)
	end

	--	// Panel

	if NoticeFunction then NoticeFunction(Ratio,PixelPerStud,MouseLocation,TopLeftPos,BottomRightPos,Size,BackgroundSettings,PADDING,BUTTON_PADDING) end

	for i, v in ipairs(Panels) do 
		v["Function"](Ratio,PixelPerStud,MouseLocation,TopLeftPos,BottomRightPos,Size,BackgroundSettings,PADDING,BUTTON_PADDING)
	end

end

RunService:BindToRenderStep("MenuAnimation",Enum.RenderPriority.Camera.Value+1,MenuAnimation)

This is the main math behind the 3D menu. This section itself is already a tad messy, the rest of the script is worse lol. Anyway, this is the important part

Also, change Mouse.Y+36 to Mouse.Y + GuiService.GuiInset.Height (or whatever it is)

1 Like

the section to calculate the world position of the corners is so smart! good job and thanks for sharing :slight_smile:

1 Like

Hey! I know im like super late but honestly I feel like it looks natural that it goes away when you aim in. To be honest when the player is aimed in they want to be focused at what their shooting at and I feel like the UI going away actually makes it seem more immersive even though its technically a bug lol.

2 Likes

Mish and I recently made a module that simplifies this into oblivion:

daang, nice! you’re a legend, thanks for making it more accessible!

1 Like