Need help on custom 3D Guis

  1. What do you want to achieve? Keep it simple and clear!
    I want to make a cool 3D gui that tilts slightly towards the mouse when the mouse enters the gui
    Here’s what I want to achieve:

Here’s what I got working so far:

  1. What is the issue? Include screenshots / videos if possible!
    I can’t get it to work, so far, I have gotten the tilting right as seen in my video but I can’t seem to figure out how I can make the part with the surface gui act like a screengui and lock onto the screen (the creator said that it was just a part with a surface gui).

  2. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I tried parenting the part to a viewportframe but viewportframes doesn’t render surfaceguis and I’m pretty sure that it also doesn’t render transparency. In addition to this, the script that I wrote didn’t work inside a viewportframe. I tried searching for solutions on the developer hub but couldn’t find a solution that matched my case. Here’s the script if needed:

local Part = game.Workspace.Part2

local Players = game:GetService("Players")

local Player = Players.LocalPlayer

local Mouse = Player:GetMouse()

local TweenService = game:GetService("TweenService")

local maxAngle = math.rad(10) 

local originalCFrame = Part.CFrame

local _, _, originalZ = originalCFrame:ToEulerAnglesYXZ()

local function animatePart(newCFrame, speed)
	local tweenInfo = TweenInfo.new(speed, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
	local tween = TweenService:Create(Part, tweenInfo, {CFrame = newCFrame})
	tween:Play()
end

Mouse.Move:Connect(function()
	if Mouse.Target == Part then
		local newCFrame = CFrame.new(Part.Position) * CFrame.new(0, 0, -1) * CFrame.lookAt(Part.Position, Mouse.Hit.Position)
		local y, x, z = newCFrame:ToEulerAnglesYXZ()
		x = x/20
		x = math.clamp(x, -maxAngle, maxAngle)
		y = math.clamp(y, -maxAngle, maxAngle)
		z = originalZ
		newCFrame = CFrame.new(Part.Position) * CFrame.fromEulerAnglesYXZ(y, x, z)

		animatePart(newCFrame, 1)
	else
		animatePart(originalCFrame, 0.5)
	end
end)

You can lock a part to the screen by making its position constant in camera space. That means your part’s position (all part properties are in World Space), must be some constant position times the camera cframe.

1 Like

So basically converting the local space of the part to the world space of the camera’s cframe?

Yes. You would do something like myCamera.CFrame * guiPosition, the guiPosition can then be thought of as being in camera space, the result is in world space.

2 Likes

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