Hello,
I am trying to replace 2D UIs with 3D UIs, how I currently set it up is I set the Adornee of the SurfaceGui to a Part that is parented to the Camera and changes the CFrame to stay with the Camera with added offsets and spring offsets etc etc. I have looked at a few resources explaining how to make 3D UIs behaving like 2D but they are complicated and don’t solve what specific issue I’m having
Everything has been going well but I have been having issues with keeping them on the screen like how ScreenGuis do. EXAMPLE BELOW
I know the solution needs some math and I am not really good at math so any help would be greatly appreciated.
This is my module’s update code:
-- GUIObject is the Part the SurfaceGui is Adorned to
-- You do not need to worry about the SpringOffsets
--[[
self.Offsets is a table and it looks like this: {
Position = Vector3.new(x,x,x),
Rotation = Vector3.new(x,x,x), -- Don't worry about this.
Size = Vector3.new(x,x,x) -- Don't worry about this.
}
]]
function GUI3D:Update(dt)
local GUIObject = self.GUIObject
local Offsets = self.Offsets
local SpringOffsets = {
Position = Vector3.zero,
Rotation = Vector3.zero,
Size = Vector3.zero
}
for i,v in self.SpringOffsets do
v:update(dt)
if SpringOffsets[i] then
SpringOffsets[i] = v.Position
end
end
local ScreenSize = Camera.ViewportSize
local FOV = math.rad(Camera.FieldOfView)
local Ratio = ScreenSize.X/ScreenSize.Y
local PositionOffset = Offsets.Position + SpringOffsets.Position
local RotationOffset = Offsets.Rotation + SpringOffsets.Rotation
local SizeOffset = Offsets.Size + SpringOffsets.Size
local OffsetRotation = CFrame.Angles(RotationOffset.X, RotationOffset.Y, RotationOffset.Z)
local SizeX = SizeOffset.X*(Ratio)/FOV
local SizeY = SizeOffset.Y*(Ratio)/FOV
local PosX = PositionOffset.X*(Ratio)/FOV
local PosY = PositionOffset.Y*(Ratio)/FOV
local FinalOffset = Camera.CFrame * CFrame.new(PosX, PosY, PositionOffset.Z)
GUIObject.CFrame = FinalOffset * CFrame.Angles(0, math.rad(180), 0)
GUIObject.Size = Vector3.new(SizeX, SizeY, .1)
end
return GUI3D