{"id":"raiven4ever/screen-3d","name":"screen-3d","scope":"raiven4ever","platform":"roblox","description":"Fork of CatGuyMoment/Screen3D, the 3D UI framework from the Roblox DevForum Screen3D post","version":"0.1.1","latest":"0.1.1","versions":["0.1.1"],"license":"Unlicense","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"468419dd1d37bb6c320f627f11e130d88b5df7b42a5f67f258a2fc648cb15a7d","likes":0,"downloads":0,"install":"forest install raiven4ever/screen-3d","url":"https://forest.dev/p/roblox/raiven4ever/screen-3d","files":"https://api.forest.dev/ai/package/roblox/raiven4ever/screen-3d/files","readme":"# Screen3D\n\nScreen3D projects Roblox `ScreenGui` interfaces into 3D space. It lets you keep building UI with normal 2D `GuiObject`s, then opt individual objects into world-space projection through `Component3D`.\n\nThis repository is a fork of [CatGuyMoment/Screen3D](https://github.com/CatGuyMoment/Screen3D), originally introduced in the Roblox Developer Forum post [Screen3D - A 3D UI framework that just works](https://devforum.roblox.com/t/screen3d-a-3d-ui-framework-that-just-works/3273671).\n\n## Purpose\n\nScreen3D is the original framework: it owns the projection logic and defines how everything works.\n\nThis repo is a fork focused on packaging and polish. It wraps Screen3D as a typed Luau dependency for Wally, cleans up naming and formatting, documents the public API, and exports the Screen3D and Component3D types from the package root.\n\nThe original is the source of truth; this is just a better way to consume it.\n\n## What It Does\n\n- Creates a `Screen3D` object from a `ScreenGui`\n- Indexes every `GuiObject` descendant as a `Component3D`\n- Converts selected 2D UI objects into `SurfaceGui`-backed 3D UI\n- Supports rotating and moving projected UI through `CFrame` offsets\n- Supports nested projected UI objects\n- Lets 2D and 3D UI objects coexist in the same hierarchy\n- Lets you choose when projected components update\n\n## Installation\n\nThis package includes a Wally manifest:\n\n```toml\n[dependencies]\nscreen3d = \"raiven4ever/screen-3d@0.1.0\"\n```\n\nInstall dependencies with Wally, then require the package from your project's package location.\n\n## Basic Usage\n\nCreate a `Screen3D` object from an existing `ScreenGui`:\n\n```lua\nlocal screen_gui: ScreenGui = path.to.your.ScreenGui\nlocal Screen3D = require(path.to.Screen3D)\n\nlocal screen_3d = Screen3D.new(screen_gui, 5)\n```\n\nThe second argument is the display distance from the camera. Creating the `Screen3D` object indexes the `GuiObject` descendants, but it does not immediately convert them into 3D UI.\n\nTo project a specific `GuiObject`, get its matching `Component3D` and enable it:\n\n```lua\nlocal frame = screen_gui:WaitForChild(\"Frame\") :: GuiObject\nlocal component_3d = screen_3d:GetComponent3D(frame)\n\nif component_3d then\n\tcomponent_3d:Enable()\n\tcomponent_3d:Update()\nend\n```\n\n`Component3D:Enable()` moves the `GuiObject` into a `SurfaceGui`. `Component3D:Update()` refreshes its canvas size, backing part size, and world-space transform.\n\nUnlike upstream, components do not create their own `RenderStepped` connections. To match the original automatic behavior, call `Update()` from one shared `RenderStepped` connection:\n\n```lua\nlocal RunService = game:GetService(\"RunService\")\n\nRunService.RenderStepped:Connect(function()\n\tif component_3d then\n\t\tcomponent_3d:Update()\n\tend\nend)\n```\n\nUse `Component3D:Disable()` to stop projection and restore the object to its 2D parent.\n\n## Offsets\n\nEach `Component3D` has an `Offset` property. The offset is applied around the UI object's anchor point and can rotate or move the projected object relative to its parent.\n\n```lua\nlocal frame = screen_gui:WaitForChild(\"Frame\") :: GuiObject\nlocal component_3d = screen_3d:GetComponent3D(frame)\n\nif component_3d then\n\tcomponent_3d:Enable()\n\tcomponent_3d.Offset = CFrame.Angles(0, math.rad(10), 0)\n\tcomponent_3d:Update()\nend\n```\n\nOffsets can be changed continuously:\n\n```lua\nlocal RunService = game:GetService(\"RunService\")\n\nRunService.RenderStepped:Connect(function()\n\tif component_3d then\n\t\tcomponent_3d.Offset = CFrame.Angles(0, math.sin(os.clock()) / 2, 0)\n\t\tcomponent_3d:Update()\n\tend\nend)\n```\n\nYou can combine position and rotation to create an indented or angled panel:\n\n```lua\nif component_3d then\n\tcomponent_3d.Offset = CFrame.new(0, 0, -0.1) * CFrame.Angles(0, math.rad(-6), 0)\n\tcomponent_3d:Update()\nend\n```\n\n## Nesting\n\nProjected components can be nested. A child `Component3D` follows the transform of its projected parent while keeping its own `Offset`.\n\n```lua\nlocal frame = screen_gui:WaitForChild(\"Frame\") :: GuiObject\nlocal inner = frame:WaitForChild(\"Inner\") :: GuiObject\n\nlocal frame_3d = screen_3d:GetComponent3D(frame)\nlocal inner_3d = screen_3d:GetComponent3D(inner)\n\nif frame_3d and inner_3d then\n\tframe_3d:Enable()\n\tinner_3d:Enable()\n\n\tinner_3d.Offset = CFrame.Angles(0, math.rad(25), 0)\n\tframe_3d:Update()\n\tinner_3d:Update()\nend\n```\n\nYou do not need to enable an entire UI tree just to rotate one object. 2D UI can contain 3D components, and 3D components can contain more projected children.\n\n## API\n\nThe package root returns the `Screen3D` class. Public Luau types are re-exported from `init.lua` and are defined in `Types.lua`.\n\n```lua\nlocal Screen3D = require(path.to.Screen3D)\n\ntype Screen3D = Screen3D.Screen3D\ntype Component3D = Screen3D.Component3D\n```\n\n### `Screen3D`\n\n```lua\nlocal screen_3d = Screen3D.new(screen_gui, display_distance)\n```\n\n- `Screen3D.new(screen_gui, display_distance)` creates projection state for a `ScreenGui`\n- `screen_3d:GetComponent3D(gui_object)` returns the indexed `Component3D`, or `nil`\n- `screen_3d:GetRealCanvasSize()` returns the camera viewport size\n- `screen_3d:GetInset()` returns the GUI inset\n- `screen_3d:GetInsetCanvasSize()` returns viewport size minus GUI inset\n- `screen_3d:GetIntendedCanvasSize()` respects `ScreenGui.IgnoreGuiInset`\n\n### `Component3D`\n\n- `component_3d:Enable()` starts projection\n- `component_3d:Update()` refreshes the projected canvas size, part size, and transform\n- `component_3d:Disable()` stops projection\n- `component_3d:EnableCompatibility()` enables wrapper-frame compatibility behavior for nested layouts\n- `component_3d.Offset` controls local projected rotation and position\n- `component_3d:GetViewportSize()` returns the active canvas size for the component\n- `component_3d:ReadWorldCFrame()` computes the current world-space transform\n\n## Notes\n\n- Projection is opt-in for performance: creating `Screen3D` only indexes objects.\n- Projection updates are manual: use one shared `RenderStepped` connection when you want continuous tracking.\n- Manual updates avoid creating one `RenderStepped` connection per enabled component.\n- `Offset` pivots around the original UI object's `AnchorPoint`.\n- For angled corner panels, set the UI object's `AnchorPoint` to the pivot you want before enabling projection.\n- True curved GUI is not provided by this module; the original forum thread discusses Roblox engine limitations around curvature.\n\n## Differences From The Original Files\n\nThis fork is based on the original author's `Component3D.luau`, `Definitions.luau`, and `init.luau`, with manual update behavior inspired by [Contrastual/Screen3D](https://github.com/Contrastual/Screen3D).\n\nMain differences:\n\n- Files were renamed from `.luau` to `.lua`.\n- The shared type definitions live in `Types.lua`, replacing the original `Definitions.luau`.\n- Types were rewritten as plain exported object-shape types and documented there.\n- Class/table names and public fields use PascalCase conventions.\n- Formatting and comments were cleaned up.\n- `Component3D` objects update through explicit `Component3D:Update()` calls instead of one automatic `RenderStepped` connection per component.\n- A duplicate `GetStudsScreenSize` call in `UDim2ToCFrame` was removed.\n- Wally metadata, licensing, and this README were added for packaging.\n\n## Credits\n\nOriginal project: [CatGuyMoment/Screen3D](https://github.com/CatGuyMoment/Screen3D)\n\nOriginal DevForum resource: [Screen3D - A 3D UI framework that just works](https://devforum.roblox.com/t/screen3d-a-3d-ui-framework-that-just-works/3273671)\n\nManual update behavior inspired by [Contrastual/Screen3D](https://github.com/Contrastual/Screen3D).\n\nThis fork is maintained under `raiven4ever/screen-3d`.\n","readmeTruncated":false}