How to create 3D UI?

Hello everyone, I want to know how to create a UI Element that can rotate in a 3D plane.

I currently have a small system that binds the SurfaceGui to the player’s camera locally and rotates it based on the player’s movement.

image

Depending on where the player turns his camera, it should go in the opposite direction, but not exceed 90°


Here’s a video of what it should look like

local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")

local UI = workspace:WaitForChild("UI")
local Camera = workspace.CurrentCamera

RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value + 1, function()
	TweenService:Create(UI, TweenInfo.new(.15, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
		CFrame = Camera.CFrame + Camera.CFrame.LookVector * 10
	}):Play()
end)

I would use this method but there are some problems here:

  1. The animation plays even when I move rather than rotating the camera
  2. UI rotates in the same direction as the camera, not in the opposite direction
  3. Too many requests in TweenService

TweenService is the only thing that came to my mind, since I don’t know what else can be done, please help me with this!

I also want to know how to move the UI around the screen so that it is not only in the center, but for example at the bottom, but also rotates as if it were in the center.


This is what happens if I move a piece down using multiplication:

local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")

local UI = workspace:WaitForChild("UI")
local Camera = workspace.CurrentCamera

RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value + 1, function()
	TweenService:Create(UI, TweenInfo.new(.15, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
		CFrame = Camera.CFrame + Camera.CFrame.LookVector * Vector3.new(10, 20, 10)
	}):Play()
end)

The problem is that the UI starts to move up or down, rather than staying in place like with the center.

It should rotate about its center, and not go up or down.


I also want to note that viewport will not help in this case.
Any help is welcome!

4 Likes

I quickly whipped this up, is this that functionality your going for?
@yo9sa

1 Like

Yes, that’s it! How did you do it lol?

1 Like

By the way, it’s you from that post! I see you succeeded with the game, good job!

1 Like

Basically I’ll expain first then i’ll give the code, so basically how it works is that it creates a unit ray using the ScreenPointToRay function that the camera provide, and then I pass in the ViewSize of the screen, and pass that to the X and Y arguments, and then of course I give a depth of how far or how near I want it to be to the camera

After that I use the mouse delta so I can get where the mouse was at last frame (not sure what it actually is but i think thats close) and we basically use the X and Y values of that and rotate the camera using that, and we use the origin and direction of that unity ray to construct the cframe aswell

local UserInputService = game:GetService("UserInputService")
local camera = workspace.CurrentCamera
local UI = workspace.UI

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local Turn = 0
local Turn2 = 0

local Lerp = function(a, b, t)
	return a + (b - a) * math.clamp(t, 0, 1)
end;

game:GetService("RunService").RenderStepped:Connect(function(deltaTime)

   local MouseDelta = UserInputService:GetMouseDelta()

   Turn = Lerp(Turn, math.clamp(MouseDelta.X, -6, 6), (15 * deltaTime))
   Turn2 = Lerp(Turn2, math.clamp(MouseDelta.Y, -6, 6), (15 * deltaTime))

   local ray = camera:ScreenPointToRay(mouse.ViewSizeX/2, mouse.ViewSizeY/2,  10)
   UI.CFrame = CFrame.lookAt(ray.Origin + ray.Direction, camera.CFrame.Position) * CFrame.Angles(math.rad(Turn2),-math.rad(Turn),0)
end)

@yo9sa Also thank you, I’m not sure i remember you but yeah my game suceeded somewhat

4 Likes

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