Roblox guide: 3d GUI!

this has alot of errors on my side, its good but i recommended just giving the entire script in one box and checking for errors. Thank you

1 Like

this is amazing :sob: better than everything I ever made

1 Like

YeašŸ˜­ they managed to put a minimap on there which Iā€™m just very impressed to be honest.
Probably going to do the same but in a different way.
Debut rays maybe for character hit scan but besides that Iā€™m going to try to get into contact with them for the ā€œworkingā€ code because I sadly wasnā€™t able to get the tutorial parts to work :rage:

1 Like

I dont really have a full, working code right now, but tomorrow if I remember I will send one

thank you the mini map was so annoying it kept breaking. id be happy to help you make the gui work cause when i got it to finally work i was so happy

Can I contact you through discord or Roblox messages? Thank you so much for your time though. I will share some of my secrets in exchange as well lol

1 Like

message me on forum dms

bruh

I tried using this tutorial, uhh yeah the code doesnt works, from stuff like ā€œMath.Radā€ and the cool error you get.
image
it would be cool if it worked tho.

Hey could you just drop the file? I know it defeated the purpose of this but I cannot seem to get it to work even after 2 weeks

1 Like

Hey my ui works great but do you know how i could make it work when i change FOV?
this is what happens when i zoom in:

(also rate the ui and gunmodel i made them myself)

  • amazing
  • good
  • meh
  • disgusting

0 voters

Iā€™m pretty sure that what I did is use Camera:ViewportPointToRay() at the top left corner and bottom right, at X studs distance, to get the screen size in studs basically, and then position the parts within the two points. At that point, since you have the screen size in studs, and the bounds, you can position it kind of like normal UI, with some CFrame math

If you want, I can dig up the code tomorrow, the code isnā€™t very pretty though lol

It also resizes dynamically, depending on the screen size

4 Likes

i forgot about this! im gonna make it right now

ok ok, i fixed it, i did a lot of typos on the script, but its back at its prime, hereā€™s the updated thing:

local plr = game.Players.LocalPlayer
local playerGui = plr.PlayerGui

local frame = Instance.new("Part")
frame.Size = Vector3.new(100, 10, 0.5)
frame.CanCollide = false
frame.CanQuery = false
frame.CanTouch = false
frame.CastShadow = false
frame.Massless = true
frame.Transparency = 1
frame.Name = "3d ui frame"
frame.Parent = workspace

local surface = Instance.new("SurfaceGui")
surface.Adornee = frame --connect it to the frame we just made
surface.Face = Enum.NormalId.Back --set its side to Back
surface.PixelsPerStud = 512 --set the PPS, can be anything but i recomment 512
surface.ClipsDescendants = false
surface.AlwaysOnTop = true --make it always visible
surface.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud
surface.Parent = playerGui --and finally, make it parented to playerGui

game:GetService("RunService").RenderStepped:Connect(function()
	local camera = workspace.CurrentCamera
	local xRatio = camera.ViewportSize.X/camera.ViewportSize.Y
	local yRatio = camera.ViewportSize.Y/camera.ViewportSize.X

	local offset = Vector3.new(
		1.8, --horizontal scale
		-5, --how far down or up it is
		9 --depth
	)

	local CalculatedOffset = Vector3.new(
		offset.X * xRatio,
		offset.Y * yRatio,
		-offset.Z)
	local rotOffset = Vector3.new(0, -20, 0)

	local calculatedRot = CFrame.Angles(math.rad(rotOffset.X), math.rad(rotOffset.Y), math.rad(rotOffset.Z))
	local newCframe = camera.CFrame * CFrame.new(CalculatedOffset) * calculatedRot
	if frame ~= nil then
		frame.CFrame = newCframe
	end
end)

nice man thanks
been waiting for a long time lol

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!