mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-24 06:34:09 +00:00
update rules
This commit is contained in:
parent
4c390fdd37
commit
d5522b2fef
8549 changed files with 11783 additions and 1888 deletions
105
.cursor/rules/roblox/en-us/studio/align-tool.md
Normal file
105
.cursor/rules/roblox/en-us/studio/align-tool.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
---
|
||||
title: Align tool
|
||||
description: The Align tool lets you align objects or groups of objects along the X, Y, or Z axes.
|
||||
---
|
||||
|
||||
The **Align** tool, accessible from Studio's **Model** tab toolbar or the **Window** ⟩ **3D** menu, lets you align objects or groups of objects along the **X**, **Y**, or **Z** axes.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Align.png" width="800" alt="Align tool highlighted in Studio's toolbar." />
|
||||
|
||||
Primary benefits include:
|
||||
|
||||
- Aligning the center or edge of multiple objects in one action.
|
||||
- Aligning entire `Class.Model|Models` or parts within them relative to other parts, all while keeping the model intact.
|
||||
- Dynamically previewing the point of alignment before confirming.
|
||||
|
||||
## Mode
|
||||
|
||||
You can set the alignment mode to either **Min**, **Center**, or **Max**.
|
||||
|
||||
<Grid container spacing={3}>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/align-tool/Icon-Min.png" width="80" alt="The Min icon in the toolbar." />
|
||||
<center><figcaption>Min</figcaption></center>
|
||||
</figure>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/align-tool/Icon-Center.png" width="80" alt="The Center icon in the toolbar." />
|
||||
<center><figcaption>Center</figcaption></center>
|
||||
</figure>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/align-tool/Icon-Max.png" width="80" alt="The Max icon in the toolbar." />
|
||||
<center><figcaption>Max</figcaption></center>
|
||||
</figure>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Min">
|
||||
<img src="../assets/studio/align-tool/Mode-Min.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are aligned with the Min button on the world Z axis. A translucent orange rectangle represents where the objects align in context to each other." />
|
||||
</TabItem>
|
||||
<TabItem label="Center">
|
||||
<img src="../assets/studio/align-tool/Mode-Center.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are aligned with the Center button on the world Z axis. A translucent orange rectangle represents where the objects align in context to each other." />
|
||||
</TabItem>
|
||||
<TabItem label="Max">
|
||||
<img src="../assets/studio/align-tool/Mode-Max.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are aligned with the Max button on the world Z axis. A translucent orange rectangle represents where the objects align in context to each other." />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Align In
|
||||
|
||||
The **World** or **Local** option specifies which relative coordinates to align on. This is especially useful for aligning parts which don't share the same orientation or rotation.
|
||||
|
||||
The **X**, **Y**, and **Z** checkboxes let you select which axes to align on. Note that you can select multiple axes in a single alignment operation.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Before Alignment">
|
||||
<img src="../assets/studio/align-tool/Align-In-Before.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are unaligned." />
|
||||
</TabItem>
|
||||
<TabItem label="Max / World Z">
|
||||
<img src="../assets/studio/align-tool/Align-In-World-Z.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are aligned with the Max button on the world Z axis. A translucent orange rectangle represents where the objects align in context to each other." />
|
||||
</TabItem>
|
||||
<TabItem label="Max / Local Z">
|
||||
<img src="../assets/studio/align-tool/Align-In-Local-Z.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are aligned with the Max button on their local Z axis. A translucent orange rectangle represents where the objects align in context to each other." />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Relative To
|
||||
|
||||
An alignment operation can be relative to either the **Selection Bounds** or the **Active Object**.
|
||||
|
||||
### Selection Bounds
|
||||
|
||||
**Selection Bounds** aligns the selected objects relative to the bounding box around them.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Before Alignment">
|
||||
<img src="../assets/studio/align-tool/Relative-To-Selection-Bounds-Before.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are unaligned. A translucent red rectangle represents where the objects' collective bounding box." />
|
||||
</TabItem>
|
||||
<TabItem label="Min / World X">
|
||||
<img src="../assets/studio/align-tool/Relative-To-Selection-Bounds-Min-X.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are aligned with the Min button on the world X axis relative to their collective bounding box. A translucent red rectangle represents where the objects' collective bounding box." />
|
||||
</TabItem>
|
||||
<TabItem label="Max / World X">
|
||||
<img src="../assets/studio/align-tool/Relative-To-Selection-Bounds-Max-X.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are aligned with the Max button on the world X axis relative to their collective bounding box. A translucent red rectangle represents where the objects' collective bounding box." />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Active Object
|
||||
|
||||
**Active Object** aligns the objects relative to the **last selected object**. This object is outlined in orange and it will not move during the operation. While parts are selected, you can switch the active object by clicking on a different object.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Before Alignment">
|
||||
<img src="../assets/studio/align-tool/Relative-To-Active-Object-Before.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are unaligned. The large blue cube has a yellow outline to represent that it's the active object." />
|
||||
</TabItem>
|
||||
<TabItem label="Min / World X">
|
||||
<img src="../assets/studio/align-tool/Relative-To-Active-Object-Min-X.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are aligned with the Min button on the world X axis relative to the active object. The large blue cube has a yellow outline to represent that it's the active object." />
|
||||
</TabItem>
|
||||
<TabItem label="Max / World X">
|
||||
<img src="../assets/studio/align-tool/Relative-To-Active-Object-Max-X.jpg" width="720" height="405" alt="An angled side view of a small red cube, large blue cube, and a small purple cube that are aligned with the Max button on the world X axis relative to the active object. The large blue cube has a yellow outline to represent that it's the active object." />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
234
.cursor/rules/roblox/en-us/studio/avatar-settings.md
Normal file
234
.cursor/rules/roblox/en-us/studio/avatar-settings.md
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
---
|
||||
title: Avatar Settings
|
||||
description: The Avatar Settings window contains all Studio-level settings and customization options for an experience.
|
||||
---
|
||||
|
||||
The **Avatar Settings** window, accessible from Studio's **File** menu or the **Avatar** tab, allows you to control the look and behavior of user avatars across your entire experience.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Avatar-Settings.png" width="800" alt="Avatar Settings indicated in Studio's toolbar" />
|
||||
|
||||
Most experiences will find that the default avatar settings work perfectly right out of the box, offering a seamless player experience. The extensive controls in **Avatar Settings** are primarily for advanced creators looking to finely tune avatar appearance and behavior for specific gameplay needs.
|
||||
|
||||
<Alert severity="warning">
|
||||
**Avatar Settings** modifies underlying experience defaults that are not visible outside of the settings interface or accessible with scripts. This can lead to difficult-to-debug behaviors, especially when working across teams or on a universe with multiple place files.
|
||||
|
||||
Test your changes by using the window's preview and by playtesting in Studio so that you fully understand the impact on player avatars before publishing changes to your live experience.
|
||||
</Alert>
|
||||
|
||||
The top bar of the **Avatar Settings** window provides easy access to quickly set the avatar type, assign a preset, and enable preview.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Preset**</td>
|
||||
<td>Displays which Settings preset is enabled and allows you to toggle between them (for descriptions of each setting, see [General](#general)). <br /><br />If the preset displays `--`, this indicates that the current settings are customized and do not match a preset.<br /> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Preview**</td>
|
||||
<td>Toggles a preview lineup of avatars based off the avatar settings applied. <br/><br/>This creates an `AvatarPreview` folder under **Workspace** ⟩ **Camera** with four representative avatar types. You can add or remove avatars to the lineup by dragging them into or out of the folder. <br/> <br/>This folder is removed during Studio runtime playtesting and it is not saved to your place file.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**⋯**</td>
|
||||
<td>Sets the default avatar type to either **R6**, **R15**, or **R15 & R6**.</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## General
|
||||
|
||||
The **General** tab offers simple presets tailored to the needs of most experiences. In many cases, one of these presets will fit your experience's avatar use-cases and additional configuration is not necessary. However, advanced developers can further customize avatar behavior using the more detailed settings available in the other tabs.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>****Player Choice****</td>
|
||||
<td>Loads player avatars without any modifications.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Consistent Gameplay**</td>
|
||||
<td>Sets all avatars to the same height with the same box collider for consistent collision behavior.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Body
|
||||
|
||||
The **Body** tab contains settings for body proportions, parts, scale.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Scale**</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>**Player Choice** (default): Does not modify avatar character scale.</li>
|
||||
<li>**Custom Scale**: Allows you to scale avatars to an absolute height in studs, but maintain their proportions. You can set a **Minimum** and **Maximum** range. </li>
|
||||
</ul>
|
||||
<br />
|
||||
<Typography variant='body1'>For reference, classic style avatars are around 5 studs tall. More humanoid style proportions are around 6 - 6.5 studs.</Typography>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Appearance**</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>**Player Choice** (default): Does not modify avatar character appearance.</li>
|
||||
<li>**Custom Parts**: Lets you override a user's default body part to a custom ID.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Build**</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>**Player Choice** (default): Does not modify avatar character proportions.</li>
|
||||
<li>**Custom Build**: Provides customization options that limits the user's avatar body type, height, width, head size, and proportions. </li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Clothing
|
||||
|
||||
The **Clothing** tab contains controls for layered and classic clothing.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Clothing Scale</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>**Player Choice** (default): Keep user's avatar clothing.</li>
|
||||
<li>**Custom Limit**: Remove any clothing that exceeds the limit bounds of the avatar.</li>
|
||||
<ul>
|
||||
<li>**Limit Bounds**: The amount of length, width, and depth padding beyond the avatar body’s bounding box, expressed as a percentage. <br /> <br />0% means no padding and items must be strictly within the bounding box of the body and 100% adds padding equal to the avatar's bounding box on all sides, allowing items to occupy up to three times the body size. <br /> <br />This limit is shown as a blue box around each avatar in the preview lineup.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Custom Clothing</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>**Player Choice** (default): Keep user's avatar clothing.</li>
|
||||
<li>**Custom Clothing**: Lets you override a user's layered clothing equip slot or classic clothing type to a custom ID. If you check the box to override, but leave the **Asset ID** field blank, it will remove all player clothing in that equip slot.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Accessories
|
||||
|
||||
The **Accessories** tab contains settings related to accessories in your experience.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Accessory Scale**</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>**Player Choice** (default): Does not change the scale of user's equipped accessories.</li>
|
||||
<li>**Custom Limit**: Allows you to **Scale** accessories, or **Remove** accessories that exceed limit bounds.</li>
|
||||
<ul>
|
||||
<li>**Limit Method**: Allows you to **Scale** accessories to fit within limit bounds, or **Remove** accessories that exceed limit bounds.</li>
|
||||
<li>**Limit Bounds**: The amount of length, width, and depth padding beyond the avatar body's bounding box, expressed as a percentage. <br /> <br />0% means no padding and items must be strictly within the bounding box of the body and 100% means pad by 100% of the bounding box on each side, so items can occupy an area three times the size of the body. <br /> <br />The limit bounds are visualized as a blue box around each avatar in the preview lineup.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Custom Accessories**</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>**Player Choice** (default): Keep user's avatar accessories.</li>
|
||||
<li>**Custom Accessories**: Lets you override a user's accessory types to a custom ID. If you check the box to override, but leave the Asset ID field blank, it will remove all player accessories of that category.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Accessory Behaviors**</td>
|
||||
<td>Controls to enable/disable accessory behaviors like VFX and Sound.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Movement
|
||||
|
||||
The **Movement** tab contains collision and animation settings.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Collision**</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>**Default**: Use Outer Box method for collisions. This method calculates collisions based off the bounding boxes of avatar parts. </li>
|
||||
<li>**Single Collider**: Use a single consistently sized box for collisions.</li>
|
||||
<ul>
|
||||
<li>**Size**: Set the length, width, and depth of the collider box.</li>
|
||||
<li>**Hit & Touch Detection**: Set hit and touch events to use avatar **parts** or **colliders**.</li>
|
||||
</ul>
|
||||
<li>**Legacy**: Use Inner Box Collision method (for backwards compatibility only).</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Animation Packs**</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>**Player Choice** (default): Keep user's platform animation style, including style packs</li>
|
||||
<li>**Standard R15**: All avatars will use the Standard R15 platform animations.</li>
|
||||
<li>**Standard R6**: All avatars will use the Standard R6 platform animations.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Animation Clips**</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>**Player Choice** (default): Keep user's platform animations.</li>
|
||||
<li>**Custom Clips**: Lets you override and preview any default animation type with a custom ID. These overrides are applied **on top of your selection of Animation Pack**.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
375
.cursor/rules/roblox/en-us/studio/build-studio-widgets.md
Normal file
375
.cursor/rules/roblox/en-us/studio/build-studio-widgets.md
Normal file
|
|
@ -0,0 +1,375 @@
|
|||
---
|
||||
title: Studio widgets
|
||||
description: Building custom widgets in Studio allows you to customize workflows and views.
|
||||
---
|
||||
|
||||
Studio gives you the power to create custom **widgets** and use them as tools and extensions. These widgets behave as custom windows/panels in Studio, and you can dock them inside of your interface or have them float as separate windows.
|
||||
|
||||
## Create widget UIs
|
||||
|
||||
All Studio widgets begin as `Class.DockWidgetPluginGui` objects which you can fill with `Class.GuiObject|GuiObjects`, such as text labels and buttons. To create an empty widget GUI, call the `Class.Plugin:CreateDockWidgetPluginGui()|CreateDockWidgetPluginGui()` function, passing in an ID and a `Datatype.DockWidgetPluginGuiInfo` object.
|
||||
|
||||
Note the `Datatype.DockWidgetPluginGuiInfo.new()` constructor expects its parameters in a **specific order** as follows:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Property</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>`Enum.InitialDockState`</td>
|
||||
<td>Enum</td>
|
||||
<td>One of the `Enum.InitialDockState` enumerations.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td>`InitialEnabled`</td>
|
||||
<td>Boolean</td>
|
||||
<td>The initial enabled (visible) state of the widget GUI.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
<td>`InitialEnabledShouldOverrideRestore`</td>
|
||||
<td>Boolean</td>
|
||||
<td>If true, the value of **InitialEnabled** overrides the previously saved enabled state.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4</td>
|
||||
<td>`FloatingXSize`</td>
|
||||
<td>Integer</td>
|
||||
<td>The initial width of the GUI when **InitialDockState** is set to `Enum.InitialDockState.Float`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>5</td>
|
||||
<td>`FloatingYSize`</td>
|
||||
<td>Integer</td>
|
||||
<td>The initial height of the GUI when **InitialDockState** is set to `Enum.InitialDockState.Float`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>6</td>
|
||||
<td>`MinWidth`</td>
|
||||
<td>Integer</td>
|
||||
<td>The minimum width of the GUI, with some platform-specific variations.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>7</td>
|
||||
<td>`MinHeight`</td>
|
||||
<td>Integer</td>
|
||||
<td>The minimum height of the GUI, with some platform-specific variations.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
```lua
|
||||
-- Create new "DockWidgetPluginGuiInfo" object
|
||||
local widgetInfo = DockWidgetPluginGuiInfo.new(
|
||||
Enum.InitialDockState.Float, -- Widget will be initialized in floating panel
|
||||
true, -- Widget will be initially enabled
|
||||
false, -- Don't override the previous enabled state
|
||||
200, -- Default width of the floating window
|
||||
300, -- Default height of the floating window
|
||||
150, -- Minimum width of the floating window
|
||||
150 -- Minimum height of the floating window
|
||||
)
|
||||
|
||||
-- Create new widget GUI
|
||||
local testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)
|
||||
testWidget.Title = "Test Widget" -- Optional widget title
|
||||
```
|
||||
|
||||
<Alert severity="warning">
|
||||
You cannot use the `Class.Plugin:CreateDockWidgetPluginGui()|CreateDockWidgetPluginGui()` function in scripts. You can only call it from the command bar or a [plugin](../studio/plugins.md) script.
|
||||
</Alert>
|
||||
|
||||
### Customize widget UI
|
||||
|
||||
Once you create a widget, you can customize its user interface with `Class.GuiObject|GuiObjects` such as informative `Class.TextLabel|TextLabels` or interactive `Class.ImageButton|ImageButtons`. For example, the following code adds a basic `Class.TextButton` to the GUI window:
|
||||
|
||||
```lua
|
||||
-- Create new widget GUI
|
||||
local testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)
|
||||
testWidget.Title = "Test Widget" -- Optional widget title
|
||||
|
||||
local testButton = Instance.new("TextButton")
|
||||
testButton.BorderSizePixel = 0
|
||||
testButton.TextSize = 20
|
||||
testButton.TextColor3 = Color3.new(1,0.2,0.4)
|
||||
testButton.AnchorPoint = Vector2.new(0.5,0.5)
|
||||
testButton.Size = UDim2.new(1,0,1,0)
|
||||
testButton.Position = UDim2.new(0.5,0,0.5,0)
|
||||
testButton.SizeConstraint = Enum.SizeConstraint.RelativeYY
|
||||
testButton.Text = "Click Me"
|
||||
testButton.Parent = testWidget
|
||||
```
|
||||
|
||||
<Alert severity="info">
|
||||
Note that **you must parent the button to the widget** in the same way that you must parent any in-experience screen `Class.GuiObject` to a `Class.ScreenGui`.
|
||||
</Alert>
|
||||
|
||||
<Alert severity="warning">
|
||||
To help you build consistent, effective Studio widgets, Roblox provides a [GitHub repo](https://github.com/Roblox/StudioWidgets) that contains GUI elements with a standard "Studio" look and feel. These include checkboxes, radio buttons, and input fields which have a Studio style, and they all support dark theme.
|
||||
</Alert>
|
||||
|
||||
### Change Studio color themes
|
||||
|
||||
Effective Studio widgets ideally match the Studio **theme** setting and dynamically adjust when the theme changes. For instance, if a developer is using the dark theme, the widget's background color, images, and text labels should look nice alongside Studio's native theme colors.
|
||||
|
||||
The following code addition uses a `syncGuiColors()` function which is initially called along with a table of GUI objects to sync. Inside the function, a nested `setColors()` function loops through the objects and syncs specific aspects of them using `Class.StudioTheme:GetColor()|GetColor()` with `Enum.StudioStyleGuideColor` enums. This `setColors()` function is immediately run to sync the Studio theme, then it's connected to the `Class.Studio.ThemeChanged|ThemeChanged` event to detect future theme changes.
|
||||
|
||||
```lua
|
||||
testButton.Parent = testWidget
|
||||
|
||||
local function syncGuiColors(objects)
|
||||
local function setColors()
|
||||
for _, guiObject in objects do
|
||||
-- Sync background color
|
||||
guiObject.BackgroundColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainBackground)
|
||||
-- Sync text color
|
||||
guiObject.TextColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainText)
|
||||
end
|
||||
end
|
||||
-- Run 'setColors()' function to initially sync colors
|
||||
setColors()
|
||||
-- Connect 'ThemeChanged' event to the 'setColors()' function
|
||||
settings().Studio.ThemeChanged:Connect(setColors)
|
||||
end
|
||||
|
||||
-- Run 'syncGuiColors()' function to sync colors of provided objects
|
||||
syncGuiColors({testButton})
|
||||
```
|
||||
|
||||
### Customize mouse cursors
|
||||
|
||||
To improve the expected interaction with widget elements, you can set system-specific **mouse cursors** to GUI events, such as `Class.GuiObject.MouseEnter|MouseEnter` and `Class.GuiObject.MouseLeave|MouseLeave`. The following code demonstrates how to connect a function to the `Class.GuiObject.MouseEnter|MouseEnter` and `Class.GuiObject.MouseLeave|MouseLeave` events of `testButton` to change the mouse cursor:
|
||||
|
||||
```lua
|
||||
local function setCursor(cursorAsset)
|
||||
plugin:GetMouse().Icon = cursorAsset
|
||||
end
|
||||
|
||||
testButton.MouseEnter:Connect(function()
|
||||
setCursor("rbxasset://SystemCursors/PointingHand")
|
||||
end)
|
||||
testButton.MouseLeave:Connect(function()
|
||||
setCursor("")
|
||||
end)
|
||||
```
|
||||
|
||||
Reference the following table for a list of mouse cursors and their potential use cases:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Mouse Cursor Icon</th>
|
||||
<th>Asset</th>
|
||||
<th>Use Case</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-Pointer.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/Arrow`</td>
|
||||
<td>Default clicking and selection.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-PointingHand.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/PointingHand`</td>
|
||||
<td>Hovering over an active link/button.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-OpenHand.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/OpenHand`</td>
|
||||
<td>Hovering over a draggable item.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-GrabbingHand.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/ClosedHand`</td>
|
||||
<td>Dragging an item.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-IBeam.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/IBeam`</td>
|
||||
<td>Hovering in a text field.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-ResizeNS.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/SizeNS`</td>
|
||||
<td>Hovering over a vertical resize handle.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-ResizeEW.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/SizeEW`</td>
|
||||
<td>Hovering over a horizontal resize handle.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-ResizeNESW.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/SizeNESW`</td>
|
||||
<td>Hovering over a corner resize handle.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-ResizeNWSE.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/SizeNWSE`</td>
|
||||
<td>Hovering over a corner resize handle.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-ResizeAll.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/SizeAll`</td>
|
||||
<td>Hovering over a multi-direction resize handle.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-ResizeSplitV.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/SplitNS`</td>
|
||||
<td>Hovering over a vertical "split" handle.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-ResizeSplitH.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/SplitEW`</td>
|
||||
<td>Hovering over a horizontal "split" handle.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-Forbidden.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/Forbidden`</td>
|
||||
<td>Hovering over a locked/forbidden item.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-Wait.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/Wait`</td>
|
||||
<td>Indicating an action is in progress.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-Busy.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/Busy`</td>
|
||||
<td> Indicating the system is busy.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../assets/misc/Mouse-Icon-Crosshair.png" width="30" /></td>
|
||||
<td>`rbxasset://SystemCursors/Cross`</td>
|
||||
<td>Hovering over a pinpoint selection area.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<Alert severity="warning">
|
||||
Note that these cursor looks are only an approximation — the actual cursors match your default operating system cursors.
|
||||
</Alert>
|
||||
|
||||
## Gather user input
|
||||
|
||||
UI elements such as `Class.TextBox` and `Class.TextButton` work normally in Studio widgets, and you can build interfaces just like you normally would on Roblox. However, `Class.UserInputService` doesn't work since these services expect the main experience window to be in focus.
|
||||
|
||||
One workaround for generic input events is to create a transparent `Class.Frame` and overlay it over the entire screen. The following code sample creates a frame, and when the user clicks on the frame, the `Class.GuiObject.InputBegan` event captures keyboard input on the frame until the user clicks away:
|
||||
|
||||
```lua
|
||||
local frame = Instance.new("Frame")
|
||||
frame.BackgroundTransparency = 1 -- Hide the frame
|
||||
frame.Size = UDim2.new(1, 0, 1, 0) -- Cover the screen
|
||||
frame.Position = UDim2.new(0, 0, 0, 0)
|
||||
frame.Parent = testWidget
|
||||
|
||||
local function onInputBegan(inputObject)
|
||||
-- Process the input object here, for example detect key presses
|
||||
end
|
||||
frame.InputBegan:Connect(onInputBegan)
|
||||
```
|
||||
|
||||
## Drag-and-drop interaction
|
||||
|
||||
Using drag-and-drop interactions for your widgets is a simple way to improve the flow of data. To create this interaction, you must define the element to drag, initiate the drag, create a drop target, and process the drop action.
|
||||
|
||||
### Create drag source
|
||||
|
||||
You can start a drag action by calling
|
||||
`Class.Plugin:StartDrag()` when the user
|
||||
presses a mouse button on some UI element, typically a
|
||||
`Class.TextButton` or
|
||||
`Class.ImageButton` within a widget. The following code sample creates a single
|
||||
window widget with a text button inside it.
|
||||
|
||||
```lua
|
||||
-- Create the widget first
|
||||
local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, true, 300, 200)
|
||||
local dragSourceWidget = plugin:CreateDockWidgetPluginGui("Drag Source", widgetInfo)
|
||||
dragSourceWidget.Title = "Drag Source"
|
||||
|
||||
-- Create a TextButton that will initiate the drag
|
||||
local dragButton = Instance.new("TextButton")
|
||||
dragButton.Size = UDim2.new(1, 0, 1, 0)
|
||||
dragButton.Text = "Drag me!"
|
||||
dragButton.Parent = dragSourceWidget
|
||||
```
|
||||
|
||||
### Initiate the drag
|
||||
|
||||
When the user clicks on the
|
||||
`Class.TextButton`, you can initiate drag through the `Class.GuiButton.MouseButton1Down|MouseButton1Down()` event which fires as soon as the user presses the mouse button.
|
||||
|
||||
Within the connected function, determine the data to drag. The data's **type** should be
|
||||
reflected in the `MimeType` key, the **content** of the drag should be reflected
|
||||
within the `Data` key, and the **sender** should describe itself in the `Sender`
|
||||
key. See the `Class.Plugin:StartDrag()` page for more details.
|
||||
|
||||
```lua
|
||||
local function onButton1Down()
|
||||
local dragInfo = {
|
||||
Data = "Hello, world", -- The data being dragged
|
||||
MimeType = "text/plain", -- Describes the MIME type of the data
|
||||
Sender = "SomeDragSource", -- Describes from where the data originated
|
||||
MouseIcon = "", -- Image content to use for the cursor
|
||||
DragIcon = "", -- Image content to render under the cursor during drag
|
||||
HotSpot = Vector2.zero -- Where on the DragIcon to center the cursor
|
||||
}
|
||||
plugin:StartDrag(dragInfo)
|
||||
end
|
||||
|
||||
dragButton.MouseButton1Down:Connect(onButton1Down)
|
||||
```
|
||||
|
||||
### Create drop target
|
||||
|
||||
The `Class.PluginGui.PluginDragDropped`
|
||||
event fires when the user releases their mouse on a window during a drag. When
|
||||
this occurs, you need to define a **drop target** such as a second widget with a
|
||||
`Class.TextLabel` to detect drops.
|
||||
|
||||
```lua
|
||||
local dragTargetWidget = plugin:CreateDockWidgetPluginGui("Drop Target", widgetInfo)
|
||||
dragTargetWidget.Title = "Drop Target"
|
||||
|
||||
-- This TextLabel will display what was dropped
|
||||
local textLabel = Instance.new("TextLabel")
|
||||
textLabel.Size = UDim2.new(1, 0, 1, 0)
|
||||
textLabel.Text = "Drop here..."
|
||||
textLabel.Parent = dragTargetWidget
|
||||
```
|
||||
|
||||
### Process the drop action
|
||||
|
||||
After creating a drop target, connect the `Class.PluginGui.PluginDragDropped` event on the drop target widget:
|
||||
|
||||
```lua
|
||||
local function onDragDrop(dragData)
|
||||
print("PluginDragDropped")
|
||||
if dragData.MimeType == "text/plain" then
|
||||
textLabel.Text = dragData.Data
|
||||
else
|
||||
textLabel.Text = dragData.MimeType
|
||||
end
|
||||
end
|
||||
|
||||
dragTargetWidget.PluginDragDropped:Connect(onDragDrop)
|
||||
```
|
||||
|
||||
While a drag is still in progress, these three events fire as the user moves their mouse over a widget:
|
||||
|
||||
- `Class.PluginGui.PluginDragEntered|PluginDragEntered` – fires when the user hovers the mouse over a window
|
||||
- `Class.PluginGui.PluginDragMoved|PluginDragMoved` –
|
||||
fires repeatedly as the user moves their mouse over a window. This is useful
|
||||
for showing a "Drop here!" message.
|
||||
- `Class.PluginGui.PluginDragLeft|PluginDragLeft` – fires
|
||||
when the user's cursor leaves a window. This is useful for hiding a "Drop here!" message.
|
||||
311
.cursor/rules/roblox/en-us/studio/debugging.md
Normal file
311
.cursor/rules/roblox/en-us/studio/debugging.md
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
---
|
||||
title: Debugging
|
||||
description: |
|
||||
Debugging tools help you resolve errors and inspect scripts line-by-line as they run.
|
||||
tags:
|
||||
- Roblox Studio
|
||||
- Debugger
|
||||
- Call Stack
|
||||
- Watch
|
||||
- Breakpoints
|
||||
---
|
||||
|
||||
Studio offers many debugging tools and workflows commonly found in Integrated Development Environments (IDEs). These help you inspect and resolve errors in scripts as they run.
|
||||
|
||||
## Breakpoint debugging
|
||||
|
||||
Breakpoints are checkpoints that pause or "break" the execution of your scripts at specific lines. You can use the pauses to inspect and debug your experience, [watch](#watch) variables, and inspect the [call stack](#call-stack). Breakpoints are one of the most effective ways to debug functions, so they're one of the most important debugging tools.
|
||||
|
||||
### Management
|
||||
|
||||
In the [Script Editor](./script-editor.md), you can [insert](#insert) several types of breakpoints and edit the configuration of a breakpoint at any time, including during playtest sessions. If you edit breakpoints during a playtest session, the edits persist even after you finish it. You can also edit a breakpoint that's actively pausing your playtest session, but changes don't apply until the next playtest session.
|
||||
|
||||
#### Insert
|
||||
|
||||
Breakpoints take multiple variations and can be inserted at any line of executable code as follows:
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Standard">
|
||||
To insert a standard breakpoint at a line of code, click in the gutter directly to the right of its line number. Alternatively, right‑click in the gutter and select **Insert Breakpoint**. The breakpoint icon appears as a red circle.
|
||||
|
||||
<img alt="Standard breakpoint shown in the script gutter" src="../assets/studio/debugging/Gutter-Breakpoint.png" width="400" />
|
||||
</TabItem>
|
||||
<TabItem label="Conditional">
|
||||
A conditional breakpoint pauses your script only if a specified condition is true, so it's useful for debugging how functions execute when certain variables have certain values or if you want to break only on certain executions in a loop.
|
||||
|
||||
To insert a conditional breakpoint, right‑click in the gutter and select **Insert Conditional Breakpoint**. In the popup window that appears, enter the desired condition, such as <Typography noWrap>`var == 10`</Typography>, then click **Save**. The conditional breakpoint icon appears as a circled **=** sign.
|
||||
|
||||
<img alt="Conditional breakpoint shown in the script gutter" src="../assets/studio/debugging/Gutter-Breakpoint-Conditional.png" width="400" />
|
||||
</TabItem>
|
||||
<TabItem label="Logpoint">
|
||||
A logpoint is a special breakpoint that logs messages to the [Output](./output.md) window without pausing the script, making it useful for debugging the values of the variables before the line executes.
|
||||
|
||||
To insert a logpoint, right‑click in the gutter and select **Insert Logpoint**. In the popup window that appears, enter the desired log message, such as <Typography noWrap>`"The value of var:", var`</Typography>, then click **Save**. The logpoint icon appears as a red diamond.
|
||||
|
||||
<img alt="Logpoint shown in the script gutter" src="../assets/studio/debugging/Gutter-Breakpoint-Logpoint.png" width="400" />
|
||||
</TabItem>
|
||||
<TabItem label="Temporary">
|
||||
A temporary breakpoint offers the same [options](#edit) as other breakpoint types, except that it automatically removes itself after the first [playtest session](#workflow). This makes it ideal for quickly testing variable values or functionality without needing to disable or delete the breakpoint afterward.
|
||||
|
||||
To insert a temporary breakpoint, right‑click in the gutter and select **Insert Temporary Breakpoint**. It initially appears as red circle and then you can [edit](#edit) its options to specify the behavior.
|
||||
|
||||
<img alt="Standard breakpoint shown in the script gutter" src="../assets/studio/debugging/Gutter-Breakpoint.png" width="400" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Disable
|
||||
|
||||
To temporarily disable a breakpoint without [deleting](#delete) it, use any of the following workflows:
|
||||
|
||||
- Click the breakpoint's icon.
|
||||
- Right-click the breakpoint's icon and select **Disable Breakpoint**.
|
||||
- [Edit](#edit) the breakpoint and toggle its **Enabled** checkbox.
|
||||
|
||||
A disabled breakpoint appears as a hollow version of its enabled icon, for example a hollow circle for a disabled standard breakpoint, or a hollow diamond for a disabled logpoint.
|
||||
|
||||
<Grid container spacing={3}>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img alt="Disabled standard breakpoint shown in the script gutter" src="../assets/studio/debugging/Gutter-Breakpoint-Disabled.png" width="400" />
|
||||
<figcaption>Disabled standard breakpoint</figcaption>
|
||||
</figure>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img alt="Disabled logpoint shown in the script gutter" src="../assets/studio/debugging/Gutter-Breakpoint-Logpoint-Disabled.png" width="400" />
|
||||
<figcaption>Disabled logpoint</figcaption>
|
||||
</figure>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
#### Delete
|
||||
|
||||
To delete a breakpoint, middle-click its icon or right‑click its icon and select **Delete Breakpoint**.
|
||||
|
||||
<Alert severity="warning">
|
||||
Deleting a breakpoint deletes its **Condition** and **Log Message**. If you want to keep this information for future debugging, [disable](#disable) the breakpoint instead.
|
||||
</Alert>
|
||||
|
||||
#### Edit
|
||||
|
||||
You can edit the configuration of a breakpoint at any time, including during playtest sessions. If you edit breakpoints during a playtest session, the edits persist even after you finish it. You can also edit a breakpoint that's actively pausing your playtest session, but changes don't apply until the next playtest session.
|
||||
|
||||
To edit a breakpoint:
|
||||
|
||||
1. Right-click the breakpoint icon and select **Edit Breakpoint**.
|
||||
2. In the **Edit Breakpoint** window, configure the breakpoint as desired. You can mix these configurations together to best suit your debugging needs.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Condition**</td>
|
||||
<td>An optional expression that determines whether the breakpoint activates. If the condition is empty, the breakpoint always activates. If the condition exists, the breakpoint becomes a [conditional breakpoint](#insert) and activates only if the condition is true. For example, if you want the breakpoint to activate only if the variable `var` equals `10`, set the condition to <Typography noWrap>`var == 10`</Typography>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Log Message**</td>
|
||||
<td>An expression that prints to the [Output](./output.md) window when the breakpoint is hit. The format of the log message is the same as that of a `Global.LuaGlobals.print()` statement. For example, set the log message as <Typography noWrap>`"The value of var:", var`</Typography> to output the same message as <Typography noWrap>`print("The value of var:", var)`</Typography>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Continue Execution**</td>
|
||||
<td>Determines whether the breakpoint pauses the script if it activates. This option is disabled by default unless the inserted breakpoint is a [logpoint](#insert).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Remove Breakpoint on Hit**</td>
|
||||
<td>If checked, the breakpoint automatically removes itself after the first playtest session, effectively making it a [temporary](#insert) breakpoint.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Trigger At**</td>
|
||||
<td>The **context** of a breakpoint determines whether it should activate on the **Client** (client‑side scripts), **Server** (server‑side scripts), or **Edit** (debugging [plugin](./plugins.md) scripts). If you choose **Custom Context**, the window indicates the current trigger contexts.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Workflow
|
||||
|
||||
The typical workflow for breakpoint debugging is as follows:
|
||||
|
||||
1. Open the script you'd like to debug and [insert breakpoints](#insert) on the lines of codes that you want to examine.
|
||||
1. From Studio's mezzanine, [initiate a playtest](../studio/testing-modes.md#playtesting) to begin debugging.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Mode-Test.png" width="800" alt="Test option in the testing modes dropdown of Studio's mezzanine." />
|
||||
|
||||
1. When the script hits a breakpoint, the playtest session **pauses** unless that breakpoint is [configured](#edit) to continue execution. A yellow arrow over the breakpoint indicates which line of code executes next.
|
||||
|
||||
<img alt="Active breakpoint in the debugger showing yellow arrow" src="../assets/studio/debugging/Gutter-Breakpoint-Active.png" width="400" />
|
||||
|
||||
1. As the script pauses, inspect the [Breakpoints](#breakpoints) window, [Watch](#watch) window, [Call Stack](#call-stack) window, [Output](./output.md) window, and [Script Editor](#script-editor) to find information about variable values and function executions.
|
||||
|
||||
1. To continue executing code after hitting a breakpoint, click **Resume Scripts** in the mezzanine.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Debug-Resume-Scripts.png" width="800" alt="Resume Scripts button indicated in Studio's mezzanine" />
|
||||
|
||||
You can also execute code one line at a time with the stepping buttons in the mezzanine:
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Debug-Tools.png" width="800" alt="Breakpoint stepping buttons indicated in Studio's mezzanine" />
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Action</th>
|
||||
<th>Shortcut</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Step Into**</td>
|
||||
<td><kbd>F11</kbd></td>
|
||||
<td>The **Step Into** button moves the debugger into the code of the function on the current line. If there is no function on the current line, the debugger moves to the next line.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Step Over**</td>
|
||||
<td><kbd>F10</kbd></td>
|
||||
<td>The **Step Over** button moves the debugger to the next line of code, **not** moving into functions.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Step Out**</td>
|
||||
<td><kbd>Shift</kbd><kbd>F11</kbd></td>
|
||||
<td>The **Step Out** button moves the debugger out of the current function and to the next line of code after the function call. If the current line isn't inside a function, the debugger moves to the next line.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
1. When you're finished debugging the current session, click the **Stop** button.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Debug-Stop.png" width="800" alt="Stop button indicated in Studio's mezzanine." />
|
||||
|
||||
### Monitoring
|
||||
|
||||
Studio includes multiple windows and tools to monitor variable values and function executions while debugging. With this information, you can find the root cause of most problems in your scripts.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Debugging-Tools.png" width="800" alt="Breakpoints button indicated in Studio's toolbar" />
|
||||
|
||||
#### Breakpoints
|
||||
|
||||
The **Breakpoints** window is a unified view that shows all breakpoints within all scripts. To open it, click **Breakpoints** from Studio's **Script** tab toolbar, or navigate to the **Window** ⟩ **Debug** menu and toggle on **Breakpoints**.
|
||||
|
||||
In the window, the **Script** and **Line** columns always display, and you can toggle on/off other [configuration](#edit) columns through the **⋮** menu in the upper‑right corner. Within the **Script** column, right‑click any breakpoint to reveal an options menu to [edit](#edit), [disable/enable](#disable), [delete](#delete), or jump to the breakpoint's line within the script.
|
||||
|
||||
<img alt="Breakpoints window in Studio" src="../assets/studio/debugging/Breakpoints-Window.png" width="720" />
|
||||
|
||||
While in a debugging session, the furthest left column shows **(x3)** which indicates the multiple contexts (**Client**, **Server**, **Edit**) for the breakpoint. By expanding any breakpoint's branch, you can then click the icon next to a specific context to [disable/enable](#disable) it for that context, such as disabling a breakpoint only in the **Client** context while keeping it enabled in the **Server** context.
|
||||
|
||||
<img alt="Breakpoint expanded to show contexts" src="../assets/studio/debugging/Breakpoints-Window-Contexts.png" width="720" />
|
||||
|
||||
#### Call Stack
|
||||
|
||||
The **Call Stack** window, accessible from Studio's **Script** tab toolbar or the **Window** ⟩ **Debug** menu, shows which line of code is going to execute next when the debugger reaches a breakpoint. If you call functions from inside other functions, it indicates which lines those functions were called from, letting you confirm whether the actual call flow matches the expected flow.
|
||||
|
||||
<img src="../assets/studio/debugging/Call-Stack-Flow-Script.png" width="640" alt="Call stack flow in a script" />
|
||||
|
||||
<img src="../assets/studio/debugging/Call-Stack-Flow-Window.png" width="720" alt="Call stack flow in the Call Stack window" />
|
||||
|
||||
As the script pauses at breakpoints, use the stepping buttons in the mezzanine to step into, over, or out of a function/line as outlined in [workflow](#workflow).
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Debug-Tools.png" width="800" alt="Breakpoint stepping buttons indicated in Studio's mezzanine" />
|
||||
|
||||
#### Watch
|
||||
|
||||
The **Watch** window, accessible from Studio's **Script** tab toolbar or the **Window** ⟩ **Debug** menu, lets you actively watch variable and expression values as you step through breakpoints.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Variables">
|
||||
The **Variables** tab shows information about the current variables in [scope](../luau/scope.md), filterable by clicking the **All Scopes** button in the window's upper bar. Expanding a branch shows the members of that variable or instance and their values. You can also watch any variable by double‑click highlighting it in the [Script Editor](./script-editor.md), right‑clicking, and selecting **Add Watch** from the popup menu.
|
||||
|
||||
<img alt="Variables to watch inside a script" src="../assets/studio/debugging/Watch-Variables-Script.png" width="760" />
|
||||
|
||||
<img src="../assets/studio/debugging/Watch-Variables-Window.png" width="720" alt="Variables information in the Watch window" />
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="My Watches">
|
||||
The **My Watches** tab shows the value of variables or expressions that you define. To watch a specific expression, click an empty row in the **Expression** column and type the expression into it. This allows you to check any expression value without monitoring individual variables in the **Variables** tab or adding `Global.LuaGlobals.print()` statements in the script to check expression values.
|
||||
|
||||
<img alt="Variables to watch inside a script" src="../assets/studio/debugging/Watch-Expressions-Script.png" width="760" />
|
||||
|
||||
<img src="../assets/studio/debugging/Watch-Expressions-Window.png" width="720" alt="Expression entered into Watch window for analysis" />
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Script Editor
|
||||
|
||||
The debugger is integrated with the [Script Editor](../studio/script-editor.md). When your experience pauses at a breakpoint in a script, you can hover your mouse over the name of a variable to see its value. For example, you can see the composition of a table and its contained keys/values.
|
||||
|
||||
<img alt="Mouseover a variable in Script Editor to show value" src="../assets/studio/debugging/Script-Editor-Mouseover-Table.png" width="640" />
|
||||
|
||||
## Additional debugging tools
|
||||
|
||||
In addition to the debugger, Studio offers additional debugging tools for you to fix problems and bugs in your experience.
|
||||
|
||||
### Command Bar
|
||||
|
||||
The [Command Bar](../studio/ui-overview.md#command-bar) allows you to run Luau commands while the experience is running. It is available in Studio from the **Window** ⟩ **Script** menu and in the [Developer Console](../studio/developer-console.md).
|
||||
|
||||
### Developer Console
|
||||
|
||||
The [Developer Console](../studio/developer-console.md) provides a wide array of details including client and server output, memory usage, network performance, and more. To open console while testing or playing an experience, type `/console` into the chat or press <kbd>F9</kbd>.
|
||||
|
||||
### Log files
|
||||
|
||||
When a script prints or errors in Studio or the player app, the app records the message in a log file in the local file system. These files are located in different places depending on the operating system.
|
||||
|
||||
#### Windows
|
||||
|
||||
To access log files on Windows:
|
||||
|
||||
1. Open **File Explorer**.
|
||||
2. Navigate to the `%LOCALAPPDATA%\Roblox\logs` directory.
|
||||
3. Double-click a log to open it. Logs with the same `XXXXX` value are from the same Studio session.
|
||||
|
||||
#### Mac
|
||||
|
||||
To access log files on Mac:
|
||||
|
||||
1. Open **Finder**.
|
||||
2. In the menu bar, select **Go** ⟩ **Go to Folder...**.
|
||||
3. In the dialog, enter `~/Library/Logs/Roblox`.
|
||||
4. Double-click the result to navigate to the Roblox logs directory.
|
||||
5. Inside the directory, double-click a log to open it.
|
||||
|
||||
#### iOS
|
||||
|
||||
You can collect iOS logs using a Mac or using an iOS device.
|
||||
|
||||
<Tabs>
|
||||
<TabItem key = "1" label="Mac">
|
||||
|
||||
To access iOS log files on a Mac:
|
||||
|
||||
1. Connect the iOS device to a Mac.
|
||||
2. Open **Finder**.
|
||||
3. Navigate to **Utilities** and open the **Console** application.
|
||||
4. To populate real-time logs in the Console application, select the iOS device from the sidebar, click the **Start** button, and reproduce the issue on the iOS device.
|
||||
5. To populate archived logs in the Console application, run `sudo log collect --device-name "[iOS Device Name]"` in the **Terminal**. Make sure there are no apostrophes in the device's name or you might get an error when running the command.
|
||||
|
||||
</TabItem>
|
||||
<TabItem key = "2" label="Device">
|
||||
|
||||
To access iOS log files on an iOS device:
|
||||
|
||||
1. Press and hold both volume buttons and the top or side button on the iOS device for 1 to 1.5 seconds to start the `sysdiagnose` program. This process might take up to 10 minutes to finish.
|
||||
2. Navigate to **Settings** ⟩ **Privacy & Security** ⟩ **Analytics & Improvements** ⟩ **Analytics Data** to access the log files.
|
||||
3. Tap on the a log file to open it.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Android
|
||||
|
||||
To access log files on Android:
|
||||
|
||||
1. Navigate to **Settings** ⟩ **System** ⟩ **Developer options**.
|
||||
2. Toggle **Developer options** on.
|
||||
3. On a computer, download and install [Android Studio](https://developer.android.com/studio).
|
||||
4. In Android Studio, click **Logcat**.
|
||||
5. Connect the Android device to the computer to automatically populate **Logcat** with logs.
|
||||
92
.cursor/rules/roblox/en-us/studio/developer-console.md
Normal file
92
.cursor/rules/roblox/en-us/studio/developer-console.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
---
|
||||
title: Developer Console
|
||||
description: Developer Console is a tool for debugging your experience during testing or in production.
|
||||
---
|
||||
|
||||
import OpeningSteps from '../includes/developer-console/opening-developer-console.md'
|
||||
|
||||
The **Developer Console** is a tool for debugging your experience when testing in Studio or running it in production. It shows log messages and errors similar to the [Output](../studio/output.md) window and detailed information on [Memory](#memory), [Network](#network), and more.
|
||||
|
||||
<OpeningSteps components={props.components}/>
|
||||
|
||||
## Console sections
|
||||
|
||||
The shortcut bar at the top of the console shows the number of critical errors and warnings, client memory usage, and average ping time; click any of these to jump to its corresponding section in the console. Below the shortcut bar is a series of tools as outlined below.
|
||||
|
||||
<img src="../assets/studio/console/Console-Summary-Bar.png" width="640" />
|
||||
|
||||
### Log
|
||||
|
||||
The **Log** tool shows diagnostic messages from scripts.
|
||||
|
||||
<img src="../assets/studio/console/Log-Sections.png" width="780" />
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Client/server toggle">
|
||||
|
||||
Using the client-server switch, you can toggle between **Client** and **Server** views:
|
||||
|
||||
- The **Client** view shows output from client-side `Class.LocalScript|LocalScripts` and/or `Class.Script|Scripts` with `Class.Script.RunContext|RunContext` set to `Enum.RunContext.Client`. Anyone running an experience can view local output messages.
|
||||
- The **Server** view shows output from server-side `Class.Script|Scripts` (`Class.Script.RunContext|RunContext` set to `Enum.RunContext.Server` or `Enum.RunContext.Legacy`). Only the experience owner or [group](../projects/groups.md) members with editing permission can view server output messages.
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Output filters">
|
||||
|
||||
Using the checkboxes, you can filter output messages in the log:
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Output**</td>
|
||||
<td>Messages generated by calls to `Global.LuaGlobals.print()` and `Global.RobloxGlobals.warn()` statements within scripts.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Information**</td>
|
||||
<td>Messages generated by the experience that aren't errors or custom output statements.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Warning**</td>
|
||||
<td>Messages that indicate a potential problem but not a critical issue.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Error**</td>
|
||||
<td>Messages that indicate that something critical has happened.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Command bar">
|
||||
|
||||
The **Server** view also includes a command bar that lets users with editing permissions run arbitrary Luau code. Unlike the [Command Bar](../studio/ui-overview.md#command) in Studio, this console command bar has the same security restrictions as `Class.Script|Scripts` and `Class.LocalScript|LocalScripts`, so it can't run protected functions.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Memory
|
||||
|
||||
**Developer Console** provides two tools for monitoring memory usage, including:
|
||||
|
||||
- **Memory** — View real-time memory consumption by usage categories, including memory usage by both your custom components and the engine internal processes.
|
||||
|
||||
- **Luau heap** — Create snapshots on the heap memory, which refers to the memory allocation to your scripts. This tool provides various memory allocation views to help you identify current memory allocation and issues from different perspectives, such as object types and engine classes. It also allows you to create multiple snapshots to compare differences in memory usage over time.
|
||||
|
||||
For more information, see [Memory Usage](../studio/optimization/memory-usage.md)
|
||||
|
||||
### Network
|
||||
|
||||
The **Network** tool shows the number of web calls that the experience has made. This includes explicit calls made through `Class.HttpService` and web requests made by Roblox services like `Class.DataStoreService`. The **Network** tool has two sections:
|
||||
|
||||
- The **Summary** section lists a summary of all the web calls by type. Each type has details on the number of requests, the number of failed requests, and the amount of time that the request took.
|
||||
|
||||
- The **Details** section lists each individual web call. Each row shows the HTTP method, such as `GET` or `POST`, along with the status code, time to execute, request type, and request URL. Click on a web call to see its response details, for example:
|
||||
|
||||
<figure>
|
||||
<figcaption>
|
||||
\{"Version":"1.1":"Content":\{"Headers":\[\]\},"StatusCode":"OK","ReasonPhrase":"OK","Headers":\[\],"TrailingHeaders":\[\],"RequestMessage":null,"IsSuccessStatusCode":true\}
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
### Script Profiler
|
||||
|
||||
The **Script Profiler** tool allows you to record profiling sessions of all running scripts and view their CPU time costs with custom recording and display settings. It's helpful for identifying scripts that take up the most CPU resources and slow down the performance. For more information, see [Script Profiler](../studio/optimization/scriptprofiler.md).
|
||||
276
.cursor/rules/roblox/en-us/studio/experience-settings.md
Normal file
276
.cursor/rules/roblox/en-us/studio/experience-settings.md
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
---
|
||||
title: Experience Settings
|
||||
description: The Experience Settings window contains Studio-level settings and customization options for an experience.
|
||||
---
|
||||
|
||||
The **Experience Settings** window, accessible from Studio's **File** menu, contains a wide array of Studio-level settings and customization options for Roblox experiences, including settings for [permissions](#permissions), [monetization](#monetization), [security](#security), and [localization](#localization).
|
||||
|
||||
<Alert severity="warning">
|
||||
Many settings in this window modify underlying properties in your place file that aren’t visible in Studio or accessible with scripts. This can lead to unexpected or difficult-to-debug behavior, especially when working across teams or reverting changes. Make sure you fully understand the impact of each setting before applying changes.
|
||||
</Alert>
|
||||
|
||||
## Basic Info
|
||||
|
||||
The **Basic Info** tab contains general settings for an experience, such as its name, description, and promotional images.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Name**</td>
|
||||
<td>The experience's title.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Description**</td>
|
||||
<td>A description of the experience that describes what a potential player should expect.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Content Maturity Label**</td>
|
||||
<td>[Content Maturity Labels](../production/promotion/content-maturity.md) provide information on the experience's main page about what kind of content the experience contains.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Game Icon**</td>
|
||||
<td>Lets you upload an [icon](../production/publishing/experience-icons.md) to represent your experience.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Screenshots & Videos**</td>
|
||||
<td>Lets you upload [promotional thumbnails](../production/publishing/thumbnails.md). </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Playable Devices**</td>
|
||||
<td>Lets you enable each applicable device that supports your experience.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Communication
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Enable Microphone**</td>
|
||||
<td>Enables voice-eligible users to use voice chat within your experience. See [Voice Chat](../chat/voice-chat.md) for more information.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Enable Camera**</td>
|
||||
<td>Enables eligible users to animate their avatar with their camera in your experience. See [Animate Your Avatar](https://en.help.roblox.com/hc/en-us/articles/17877687557396) for more information.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Permissions
|
||||
|
||||
The **Permissions** tab lets you control the audience for your experience.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Playability**</td>
|
||||
<td>Sets which users can access the experience.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Monetization
|
||||
|
||||
The **Monetization** tab contains settings that let you [monetize](../production/monetization/index.md) your experience.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Badges**</td>
|
||||
<td>Lets you create and manage all [badges](../production/publishing/badges.md) for your experience.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Paid Access**</td>
|
||||
<td>Lets you enable [paid access in Robux](../production/monetization/paid-access-robux.md) or [paid access in local currency](../production/monetization/paid-access-local-currency.md).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Private Servers**</td>
|
||||
<td>Lets you enable [private servers](../production/monetization/private-servers.md).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Developer Products**</td>
|
||||
<td>Lets you create and manage all [developer products](../production/monetization/developer-products.md) for your experience.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Security
|
||||
|
||||
The **Security** tab contains settings related to network communication, sales, and teleports.
|
||||
|
||||
<Alert severity="warning">
|
||||
You should only enable the following settings if you trust all assets from other users or groups within your experience, otherwise your experience is vulnerable to security risks.
|
||||
</Alert>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Allow HTTP Requests**</td>
|
||||
<td>Allows experiences' servers to issue requests to remote servers via `Class.HttpService`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Secrets**</td>
|
||||
<td>Allows for the creation and configuration of `Datatype.Secret|Secrets` for local Studio sessions using `Class.HttpService`. For more information, see [Work with secrets](../cloud-services/secrets.md#local-secrets).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Enable Studio Access to API Services**</td>
|
||||
<td>Lets Studio access API services. This setting is useful for testing the implementation of services like [data stores](../cloud-services/data-stores).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Allow Third Party Sales**</td>
|
||||
<td>Lets players purchase items from third parties. When this setting is disabled, all purchase prompts from assets you own will continue to work while purchase prompts from assets published by other users or groups will fail.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Allow Third Party Teleports**</td>
|
||||
<td>Lets players [teleport](../projects/teleport.md) to other experiences.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Allow Mesh / Image APIs**</td>
|
||||
<td>Lets you use `Class.EditableImage` and `Class.EditableMesh` in published experiences. To enable usage, you must be 13+ age verified and ID verified.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Places
|
||||
|
||||
The **Places** tab contains place-specific settings.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Create**</td>
|
||||
<td>Lets you create a new place within your experience.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**⋯**</td>
|
||||
<td>Opens a pop-up menu with options to **Configure Place** (edit place-specific settings such as the maximum number of players), or **Version History** to view, download, and open any previous version of the experience.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Localization
|
||||
|
||||
The **Localization** tab contains language settings related to [localization](../production/localization/index.md) both within the experience and in the cloud.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Source Language**</td>
|
||||
<td>Lets you choose the language that you used to create the experience.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Automatic Text Capture**</td>
|
||||
<td>Automatically captures text from the experience's UI while users are accessing the experience.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Use Translated Content**</td>
|
||||
<td>Enables translated content within the experience.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Automatic Translation**</td>
|
||||
<td>The languages for which you'd like to enable [automatic translation](../production/localization/automatic-translations.md).</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## World
|
||||
|
||||
The **World** tab includes global settings for the experience, such as
|
||||
gravity, character jump behavior, and walk speed.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Presets**</td>
|
||||
<td>Sets the options lower in the tab to presets for **Classic**, **Realistic**, or **Action**.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Gravity**</td>
|
||||
<td>Sets the overall world gravity in studs per second² (note the meters per second² equivalent in parentheses).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Jump**</td>
|
||||
<td>Sets either the humanoid **jump height** in studs or the **jump power** in studs per second. Note how adjusting this value changes the max jump distance in relation to the walk speed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Walk**</td>
|
||||
<td>Sets the humanoid walk speed in studs per second. Adjusting this value changes the **max jump distance** in relation to jump height or power.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Slope**</td>
|
||||
<td>Determines the maximum slope angle that humanoids can climb. If the angle of a slope is greater than this value, the humanoids will slide down the slope.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Other
|
||||
|
||||
The **Other** tab includes settings that are typically reserved for special situations, such as collaborative scripting and shutting down all servers.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Enable Drafts Mode**</td>
|
||||
<td>Enables asynchronous, drafts-based script editing in a [collaborative](../projects/collaboration.md) session.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Shutdown All Servers**</td>
|
||||
<td>Shuts down all servers currently running the experience.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
455
.cursor/rules/roblox/en-us/studio/explorer.md
Normal file
455
.cursor/rules/roblox/en-us/studio/explorer.md
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
---
|
||||
title: Explorer window
|
||||
description: The Explorer window shows a hierarchical list of every instance inside an experience.
|
||||
---
|
||||
|
||||
The **Explorer** window, accessible from Studio's **Window** menu or **Home** tab toolbar, shows a hierarchical list of every instance inside an experience. At the highest level of the hierarchy are the services; `Class.Workspace`, for example, is where visible 3D content such as [parts](../parts/index.md) are stored.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Explorer.png" width="800" alt="Explorer highlighted in Studio's toolbar." />
|
||||
|
||||
## Parent-child hierarchy
|
||||
|
||||
All children of a parent object appear under its branch when expanded. Click the arrow next to a parent branch — or press the <kbd>→</kbd>/<kbd>←</kbd> arrow keys when a parent is selected — to expand/collapse only that branch.
|
||||
|
||||
<Grid container spacing={3}>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/explorer/Parent-Child-Hierarchy.png" width="320" alt="Explorer hierarchy showing Camera, Terrain, and SignModel as children of Workspace; Board and Post as children of SignModel" />
|
||||
</figure>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/explorer/Branch-Expanded.png" width="320" alt="Only the topmost parent expanded with click" />
|
||||
</figure>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Alert severity="info">
|
||||
To expand or collapse **all** branches within a multi‑nested hierarchy, hold <kbd>Shift</kbd> when clicking the expand/collapse arrow.
|
||||
</Alert>
|
||||
|
||||
To change the parent of one or more children (reparent), simply drag and drop them onto the new parent.
|
||||
|
||||
<img src="../assets/studio/explorer/Reparent-Object.png" width="320" alt="Dragging one object over another to reparent it" />
|
||||
|
||||
## Object insertion
|
||||
|
||||
While primitive [parts](../parts/index.md) can be [inserted](../parts/index.md#insert-parts) from the **Home** or **Model** tab toolbars, you can select from a full array of objects by hovering over the intended parent and clicking the ⊕ button (shortcut of <kbd>Ctrl</kbd><kbd>I</kbd> on Windows or <kbd>⌘</kbd><kbd>I</kbd> on Mac).
|
||||
|
||||
<img src="../assets/studio/explorer/Workspace-Add-Object.png" width="320" alt="Hovering over Workspace object to reveal insertion button" />
|
||||
|
||||
You can further customize insertion behavior by clicking the **⋯** button to the right of the search field:
|
||||
|
||||
<img src="../assets/studio/explorer/Insert-Object-Options.png" width="320" alt="Additional customization options for insertion workflow" />
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Increment names for new instances**</td>
|
||||
<td>When enabled, inserted/pasted/duplicated instances of the same type will have numbered names for differentiation.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Expand hierarchy when selecting**</td>
|
||||
<td>When enabled, inserting/pasting an instance or selecting an object in the [3D viewport](../studio/ui-overview.md#3d-viewport) will expand the **Explorer** hierarchy to reveal that instance. When disabled, the top‑level parent within the hierarchy will be highlighted, but it won't expand to reveal the selected instance.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<Alert severity="success">
|
||||
To keep the hierarchy cleaner, services such as `Class.VoiceChatService` are hidden by default. You can show hidden services by right‑clicking in the window and selecting **Show Services…** from the context menu. Similarly, you can hide a visible service by right‑clicking it and selecting **Hide Service in Explorer**.
|
||||
</Alert>
|
||||
|
||||
## Duplicate and paste
|
||||
|
||||
Objects can be quickly duplicated into the same branch, while items copied to the clipboard can be pasted into the top‑level `Class.Workspace` or directly into one or more existing parents.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Action</th>
|
||||
<th>Windows</th>
|
||||
<th>Mac</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Duplicate**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>D</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>D</kbd></td>
|
||||
<td>Duplicates the selected objects into the same branch.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Paste**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>V</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>V</kbd></td>
|
||||
<td>Pastes the clipboard contents into the top‑level `Class.Workspace` branch.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Paste Into**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>V</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>Shift</kbd><kbd>V</kbd></td>
|
||||
<td>Pastes the clipboard contents into the selected object(s). Using this action on multiple selected objects is a convenient way to paste the same clipboard items into multiple parents, such as a common `Class.Texture` into several different `Class.Part|Parts`.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<Alert severity="info">
|
||||
When pasting 3D objects copied to the clipboard, you can maintain their original `Datatype.CFrame` position by right‑clicking the target parent instance in the hierarchy and selecting **Paste Options** ⟩ **Paste Into At Original Location**.
|
||||
</Alert>
|
||||
|
||||
## Contextual options
|
||||
|
||||
Right-clicking on an instance opens the options menu, contextually adjusted for the object type. For example, right‑clicking a `Class.Model` reveals standard options like **Copy** and **Duplicate**, and also options specific to `Class.Model|Models` like **Ungroup**. In contrast, right‑clicking a service like `Class.Lighting` reveals a more concise menu of actions valid for services.
|
||||
|
||||
<Grid container spacing={3}>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/explorer/Context-Menu-Model.png" width="320" />
|
||||
</figure>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/explorer/Context-Menu-Service.png" width="320" />
|
||||
</figure>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
## Folder organization
|
||||
|
||||
Like directories/folders on a computer, the `Class.Folder` object is a useful way to organize objects. For instance, if you want to store all environmental audio assets in a logical place, you can create a folder and place multiple `Class.AudioPlayer` objects within it.
|
||||
|
||||
<img src="../assets/studio/explorer/Folder-Children.png" width="320" alt="Multiple Sound objects grouped inside a Folder object" />
|
||||
|
||||
You can organize objects into folders as follows:
|
||||
|
||||
- Create a `Class.Folder` instance through a standard [insertion](#object-insertion) method, then drag and drop existing objects into it.
|
||||
|
||||
- Select multiple objects, right-click them, and then select **Group As a Folder** from the context menu (shortcut of <kbd>Alt</kbd><kbd>Ctrl</kbd><kbd>G</kbd> on Windows or <kbd>⌥</kbd><kbd>⌘</kbd><kbd>G</kbd> on Mac).
|
||||
|
||||
## Search methods
|
||||
|
||||
Through the **search** input near the top of the window, you can find instances by [name](#name-search), [property](#property-search), class/subclass/tag [bespoke](#bespoke-search) queries, and [ancestry](#ancestry-search) queries. You can also [combine parameters](#combined) for advanced logical searches. Quickly access this input by pressing <kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>X</kbd> (Windows) or <kbd>⌘</kbd><kbd>Shift</kbd><kbd>X</kbd> (Mac).
|
||||
|
||||
<img src="../assets/studio/explorer/Search-Diagram.png" width="360" alt="Example search query and search options" />
|
||||
|
||||
<Grid container spacing={2}>
|
||||
<Grid item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Box-Label-A.png" width="40" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Navigate up and down through search results
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Box-Label-B.png" width="40" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Select all search results (<kbd>Ctrl</kbd><kbd>A</kbd> on Windows or <kbd>⌘</kbd><kbd>A</kbd> on Mac)
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Box-Label-C.png" width="40" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Refresh search results
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Alert severity="success">
|
||||
A name is a sequence of characters that are alphanumeric, `_`, `-`, or `.`.
|
||||
In all of the following search methods, exercise caution when searching for instances whose names contain spaces, as the search logic may confuse spaces for a [combined search](#combined). When searching for names with spaces, you should surround the full name with double quotes, for example <Typography noWrap>`tag:"Light Source"`</Typography> to search by the full [tag](../studio/properties.md#instance-tags) name of <Typography noWrap>`Light Source`</Typography>.
|
||||
</Alert>
|
||||
|
||||
### Name search
|
||||
|
||||
Typing in a basic string yields **name** matched instances, case‑insensitive. For example, searching by the keyword `script` finds all instances containing it, such as `ServerScriptService` and `LocalScript`.
|
||||
|
||||
<img src="../assets/studio/explorer/Search-By-Name.png" width="320" alt="Objects filtered by query of 'script'" />
|
||||
|
||||
### Property search
|
||||
|
||||
You can filter by property equality or value comparisons. Most properties are supported, it works with partial matches, ignores spacing, and is case‑insensitive.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Equality">
|
||||
Property **equality** is searched through the operators `=` or `==`.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Example</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>`ClassName = Decal`</td>
|
||||
<td>All instances of class `Class.Decal`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Locked = true`</td>
|
||||
<td>`Class.BasePart|BaseParts` with `Class.BasePart.Locked|Locked` set to `true`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Material == plas`</td>
|
||||
<td>`Class.BasePart|BaseParts` with `Class.BasePart.Material|Material` of either `Enum.Material|Plastic` or `Enum.Material|SmoothPlastic`.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Value Comparisons">
|
||||
Property **value comparisons** are searched through the operators `~=`, `>`, `<`, `<=`, or `>=`.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Example</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>`Health > 50`</td>
|
||||
<td>Every `Class.Humanoid` with `Class.Humanoid.Health|Health` more than `50`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Transparency ~= 0.5`</td>
|
||||
<td>`Class.BasePart|BaseParts` with `Class.BasePart.Transparency|Transparency` **not** equal to `0.5`.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Individual Fields">
|
||||
Property types such as `Datatype.Vector3` and `Datatype.Color3` support searching by **individual fields**. This works either for exact equality or for value comparisons.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Example</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>`Position.X = 1`</td>
|
||||
<td>Objects with an `X` position of exactly `1`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Color.R > 120`</td>
|
||||
<td>Objects with a red (`R`) color channel value greater than `120`.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Complete Units">
|
||||
Property types such as `Datatype.Vector3` and `Datatype.Color3` support searching as a **complete unit**, with the unit surrounded by quotes. This works either for exact equality, or with comparison operators in which every value is compared against the comparator.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Example</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>`Size > "20, 5, 20"`</td>
|
||||
<td>Objects with an `X`, `Y`, and `Z` size greater than `20`, `5`, `20`, respectively.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Color = "255, 0, 0"`</td>
|
||||
<td>Objects with an RGB color value of exactly <Typography noWrap>`[255, 0, 0]`</Typography>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Bespoke search
|
||||
|
||||
Classes, and subclasses, and tags are searched through various **bespoke** queries, including:
|
||||
|
||||
- `is:[Class]` finds everything that is of **class** `[Class]`. For example, `is:Part` finds everything that is a `Class.Part`.
|
||||
- `is:[SubClass]` finds everything that is a **subclass** of `[SubClass]`. For example, `is:BasePart` finds everything that is a subclass of `Class.BasePart`, such as `Class.Part` and `Class.MeshPart`.
|
||||
- `tag:[TagName]` finds everything with a `Class.CollectionService` tag of `[TagName]`. For example, `tag:LightSource` finds everything that is tagged `LightSource`. You can add tags using the [Tags](../studio/properties.md#instance-tags) section of an instance's properties and tag names will autocomplete.
|
||||
|
||||
### Ancestry search
|
||||
|
||||
You can search within a specific scope using the `.` operator, chain operators together for highly specific searches, or use `*` as a wildcard.
|
||||
|
||||
- `[Parent].[Child]` finds named children inside a named parent. For example, `workspace.Model` finds instances named `Model` inside instances named `workspace`, similar to scripting.
|
||||
- Chaining `.` operators adds specificity. For instance, `Animals.Dog.Tail` finds objects named `Tail` inside `Dog` inside `Animals`.
|
||||
- `*` acts as a wildcard, for instance:
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Example</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>`Cart.*`</td>
|
||||
<td>All children of an object named `Cart`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Cart.Barrier.*`</td>
|
||||
<td>All children of `Barrier`, itself a child of `Cart`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Cart.*.*`</td>
|
||||
<td>All grandchildren of `Cart`, excluding direct children of `Cart`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Cart.*.Trim`</td>
|
||||
<td>All grandchildren of `Cart` that are named `Trim`.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
- `[Parent].**` finds all descendants of a parent. For example, `CarModel.**` finds all descendants of `CarModel`.
|
||||
|
||||
### Combined
|
||||
|
||||
For advanced logical searches, you can combine queries through unions and grouping.
|
||||
|
||||
- Multiple queries separated by spaces or `and` operate on **all** of the conditions.
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Example</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>`Anchored=true CanCollide=true`</td>
|
||||
<td>Every `Class.BasePart` that is anchored and can collide.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Cart.*.* Transparency < 1`</td>
|
||||
<td>All grandchildren of `Cart` that are not fully transparent.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Anchored=false and CanCollide=false`</td>
|
||||
<td>Every `Class.BasePart` that isn't anchored and can't collide.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
- The `or` conjunction operates just like the `or` operator in code. Groups within parentheses, conjoined by `or`, find everything within multiple combined queries.
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Example</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>`Cat or Dog`</td>
|
||||
<td>Everything that has `Cat` or `Dog` in its name.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`(Anchored=true CanCollide=true) or (Anchored=false CanCollide=false)`</td>
|
||||
<td>Every `Class.BasePart` that either is anchored and can collide, **or** isn't anchored and can't collide.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Selection methods
|
||||
|
||||
Within a [searched](#search-methods) hierarchy, certain key shortcuts and mouse operations behave differently than they do within a non‑searched hierarchy.
|
||||
|
||||
### Select all
|
||||
|
||||
Within a non‑searched hierarchy, pressing <kbd>Ctrl</kbd><kbd>A</kbd> on Windows or <kbd>⌘</kbd><kbd>A</kbd> on Mac selects all instances. Within a [searched](#search-methods) hierarchy, the same shortcut or the **select all** button selects only the query‑matching objects, for example all objects matching **Board** in a hierarchy searched for `board`.
|
||||
|
||||
<img src="../assets/studio/explorer/Select-All-Searched.png" width="320" alt="Image showing how only matching objects are selected in a searched hierarchy using the Select All shortcut" />
|
||||
|
||||
### Shift-select
|
||||
|
||||
Clicking an object and <kbd>Shift</kbd>-clicking another object behaves differently within a non‑searched hierarchy versus a [searched](#search-methods) hierarchy.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Non-Searched Hierarchy">
|
||||
Within a non-searched hierarchy, <kbd>Shift</kbd>-clicking two objects at the same hierarchy level selects both of them and every object between which is also at the same hierarchy level, as shown in image **🅰** where **LeftFoot** is initially clicked, **LeftLowerArm** is <kbd>Shift</kbd>‑clicked, and **LeftHand** at same hierarchy level is also selected. Duplicating, copying, or pasting the selected objects will result in a deep copy of those objects **and** all children.
|
||||
|
||||
If the first <kbd>Shift</kbd>-clicked object and the second <kbd>Shift</kbd>-clicked object are at **different** hierarchy levels, all objects in between them will be selected, as shown in image **🅱** where **LeftFoot** is initially clicked, **LeftHand** is <kbd>Shift</kbd>‑clicked, and everything between is also selected.
|
||||
|
||||
<Grid container spacing={3}>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/explorer/Shift-Click-Non-Searched-A.png" width="320" />
|
||||
<figcaption><kbd>Shift</kbd>-click at same hierarchy level</figcaption>
|
||||
</figure>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/explorer/Shift-Click-Non-Searched-B.png" width="320" />
|
||||
<figcaption><kbd>Shift</kbd>-click at different hierarchy level</figcaption>
|
||||
</figure>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem label="Searched Hierarchy">
|
||||
Within a searched hierarchy, if both the initially‑clicked object and the <kbd>Shift</kbd>‑clicked object match the query, only query‑matching objects between are selected. For example, in the following image with a hierarchy searched for `anim`, **FallAnim** is initially clicked, **RunAnim** is <kbd>Shift</kbd>‑clicked, and every object matching `anim` between is also selected.
|
||||
|
||||
<img src="../assets/studio/explorer/Shift-Click-Searched.png" width="320" alt="Image showing how only matching objects in range are selected within a searched hierarchy" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Drag select
|
||||
|
||||
Clicking and dragging from an empty region of the window initiates a selection box. Within a non‑searched hierarchy, everything inside the box is selected. Within a [searched](#search-methods) hierarchy, only query‑matching objects inside the box are selected.
|
||||
|
||||
<figure>
|
||||
<img src="../assets/studio/explorer/Drag-Select-Searched.png" width="320" alt="Image showing how only matching objects inside the selection box are selected within a searched hierarchy" />
|
||||
</figure>
|
||||
|
||||
## Key shortcuts
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Shortcut</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><kbd>→</kbd></td>
|
||||
<td>With a collapsed branch selected, expands that branch. When pressed again, selects the **first child** immediately under the parent node.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>←</kbd></td>
|
||||
<td>With any child of a branch selected, moves selection back to the parent node. When pressed again, collapses the entire branch.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Home</kbd></td>
|
||||
<td>Selects the topmost object in the hierarchy (`Class.Workspace`).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>End</kbd></td>
|
||||
<td>Selects the bottommost object in the hierarchy.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>PageUp</kbd></td>
|
||||
<td>Selects the object in the hierarchy that's above the topmost **visible** hierarchy item.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>PageDown</kbd></td>
|
||||
<td>Selects the object in the hierarchy that's below the bottommost **visible** hierarchy item.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>X</kbd><br /><kbd>⌘</kbd><kbd>Shift</kbd><kbd>X</kbd></td>
|
||||
<td>Jump to the [search input](#search-methods) near the top of the window.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
207
.cursor/rules/roblox/en-us/studio/index.md
Normal file
207
.cursor/rules/roblox/en-us/studio/index.md
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
---
|
||||
title: Roblox Studio
|
||||
description: An overview of Roblox Studio, the all-in-one IDE for Roblox creation.
|
||||
hideInPageNavigation: true
|
||||
---
|
||||
|
||||
export const sections = [
|
||||
{
|
||||
description: "Roblox Studio is free to use and has everything you need to start publishing creations to hundreds of millions of Roblox users on consoles, desktops, and mobile devices.",
|
||||
buttons: [{ text: "Get Studio", href: "/studio/setup" }]
|
||||
},
|
||||
{
|
||||
title: "Build, script, test, and publish",
|
||||
description: "Access a robust set of building, scripting, testing, and publishing tools directly in Studio.",
|
||||
content: [
|
||||
{
|
||||
title: "Easy 3D world building",
|
||||
description: "Drag and drop objects into your workspace, move and rotate to get things just right, and texture and polish your world to get the right look.",
|
||||
image: "./assets/modeling/solid-modeling/Separate-Parts-To-Union.jpg",
|
||||
links: [
|
||||
{ text: "Studio tools", href: "./studio/align-tool" }
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "An intelligent script editor",
|
||||
description: "Syntax highlighting, code completion, and inline documentation let you script easily.",
|
||||
image: "./assets/landing/scripting.png",
|
||||
links: [
|
||||
{ text: "Script editor", href: "./studio/script-editor" }
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Device emulation and playtesting",
|
||||
description: "Emulate a wide range of screen sizes and form factors to make sure everything looks and feels great before sharing your experience with the world.",
|
||||
image: "/assets/getting-started/platform-overview/Rapid-Iteration.png",
|
||||
links: [
|
||||
{ text: "Studio testing modes", href: "./studio/testing-modes" }
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Unleash the power of the Roblox engine",
|
||||
description: "Roblox Studio comes bundled with the powerful Roblox engine that runs anywhere with endless customization.",
|
||||
links: [
|
||||
{ text: "Engine API", href: "./reference/engine" },
|
||||
{ text: "Experience Guides", href: "./creation" }
|
||||
],
|
||||
content: [
|
||||
{
|
||||
title: "A standard and flexible data model",
|
||||
description: "Data models tell the engine how to render and simulate your experience. Studio can manipulate data models at both edit and runtime, allowing you to create and iterate freely.",
|
||||
image: "./assets/landing/datamodel.png",
|
||||
links: [
|
||||
{ text: "Data model", href: "./projects/data-model" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Out-of-the-box primitives and services",
|
||||
description: "Construct 3d worlds that closely simulate real life with out-of-the-box primitives like simple 3D objects, physical constraints, and services for lighting, sound, and more. Choose what Roblox provides by default or customize behavior with property overrides and scripting.",
|
||||
image: "./assets/modeling/parts/Move-World-Orientation.png",
|
||||
links: [
|
||||
{ text: "See all guides", href: "./creation" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "AI tools to accelerate creation",
|
||||
description: "Assistant lets you focus on creativity by using AI to automate mundane tasks, manipulate the data model, generate materials and textures, and more.",
|
||||
content: [
|
||||
{
|
||||
title: "Let Assistant take action",
|
||||
description: "Ask questions and get answers, or let Assistant update the data model directly. Assistant can add objects in bulk, modify scripts in place, optimize code, and much more.",
|
||||
image: "./assets/assistant/prompt12.png",
|
||||
links: [{ text: "Assistant", href: "./assistant/guide#insert-and-modify-scripts" }]
|
||||
},
|
||||
{
|
||||
title: "Generate materials and textures",
|
||||
description: "Bring your experiences to life with custom materials and textures for your 3D objects.",
|
||||
image: "./assets/studio/texture-generator/Texture-Applied.jpg",
|
||||
links: [
|
||||
{ text: "Material generator", href: "./studio/material-generator" },
|
||||
{ text: "Texture generator ", href: "./studio/texture-generator" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Rig and cage avatars",
|
||||
description: "Import character models and let Studio automatically rig and cage them to support layered clothing.",
|
||||
image: "./assets/avatar/avatar-setup/Skin-Tone-Selector.png",
|
||||
links: [{ text: "Avatar Setup tool", href: "./art/modeling/avatar-setup/" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Collaborative at its core",
|
||||
description: "Studio lets you collaboratively create in real time, with small or large teams alike.",
|
||||
links: [
|
||||
{ text: "Learn how to scale", href: "./scale" },
|
||||
{ text: "Learn how to monetize", href: "./monetize" }
|
||||
],
|
||||
content: [
|
||||
{
|
||||
title: "Real-time team creation",
|
||||
description: "Build and script collaboratively in Studio. Watch your teammates' creations come to life before your eyes.",
|
||||
image: "/assets/studio/collaboration/Collaborative-Session.jpg",
|
||||
links: [{ text: "Studio collaboration", href: "./projects/collaboration" }]
|
||||
},
|
||||
{
|
||||
title: "Group-based access",
|
||||
description: "Control access to your creations and control how multiple team members work on the same experiences, use the same assets, and share profits.",
|
||||
image: "/assets/landing/groups.jpg",
|
||||
links: [{ text: "Groups", href: "./projects/groups" }]
|
||||
},
|
||||
{
|
||||
title: "Share and access millions of assets",
|
||||
description: "You can create and access millions of freely available models, meshes images, sounds, and videos in the Creator Store.",
|
||||
image: "/assets/landing/assets.png",
|
||||
links: [{ text: "Assets", href: "./assets" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
{sections.map((section, index) => (
|
||||
<Grid style={{ marginBottom: 48}} item xs={12} key={index}>
|
||||
{section.title && (
|
||||
<Typography variant='h1'>{section.title}</Typography>
|
||||
)}
|
||||
<div style={{ marginTop: 16, marginBottom: 48 }}>
|
||||
{section.description && (
|
||||
<p>{section.description}</p>
|
||||
)}
|
||||
{section.buttons && section.buttons.map((button, btnIndex) => (
|
||||
<Button
|
||||
key={btnIndex}
|
||||
style={{ marginTop: 8, marginRight: 24 }}
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
size="large"
|
||||
href={button.href}
|
||||
>
|
||||
{button.text}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
{section.stats && (
|
||||
<Grid item xs={12} style={{ textAlign: "center", marginTop: -48, marginBottom: 48 }}>
|
||||
<Grid container spacing={4}>
|
||||
{section.stats.map((stat, statIndex) => (
|
||||
<Grid item xs={12} sm={6} md={4} key={statIndex}>
|
||||
<Card variant="filled">
|
||||
<CardContent>
|
||||
<Typography variant="hero" color="info">{stat.header}</Typography>
|
||||
<Typography component="p" variant="h2">{stat.description}</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
{section.content && (
|
||||
<Grid container spacing={4}>
|
||||
{section.content.map((content, contentIndex) => {
|
||||
const mdValue = 12 / section.content.length;
|
||||
return (
|
||||
<Grid item xs={12} sm={6} md={mdValue} key={contentIndex}>
|
||||
<div style={{ marginBottom: 48 }}>
|
||||
{content.image && (
|
||||
<img
|
||||
style={{ width: '100%', aspectRatio: 16/9, height: 'auto', objectFit: 'contain' }}
|
||||
src={content.image}
|
||||
alt=""
|
||||
/>
|
||||
)}
|
||||
{content.video && (
|
||||
<iframe style={{ width: '100%', aspectRatio: 16/9, height: 'auto' }} src={content.video} title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
)}
|
||||
<h3>{content.title}</h3>
|
||||
<p>{content.description}</p>
|
||||
{content.links && content.links.map((link, linkIndex) => (
|
||||
<a href={link.href} key={linkIndex}>
|
||||
<Typography variant='buttonLarge'>{link.text}</Typography><br />
|
||||
</a>
|
||||
))}
|
||||
{content.buttons && content.buttons.map((button, btnIndex) => (
|
||||
<Button
|
||||
key={btnIndex}
|
||||
style={{ marginTop: 16, marginRight: 24 }}
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
size="large"
|
||||
href={button.href}
|
||||
>
|
||||
{button.text}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</Grid>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
))}
|
||||
80
.cursor/rules/roblox/en-us/studio/material-generator.md
Normal file
80
.cursor/rules/roblox/en-us/studio/material-generator.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
title: Material Generator
|
||||
description: The Material Generator is designed to create material variants from text entries.
|
||||
---
|
||||
|
||||
The **Material Generator** is designed to create material variants from text entries. Using it, you can type any phrase and hit **Generate** to see results within a few seconds. Once you find a satisfying result, you can instantly save it as a new custom material.
|
||||
|
||||
## Generate materials
|
||||
|
||||
To generate materials, open the **Material Generator** from Studio's **Window** ⟩ **3D** menu, or click **Generate** from the [Material](../parts/materials.md#material-widget) widget's picker popup.
|
||||
|
||||
With the tool's window open:
|
||||
|
||||
1. In the text box at the top of the window, enter keywords and then click the **Generate** button. See [Best Practices](#best-practices) for guidelines.
|
||||
|
||||
As follows are some example keyword combos and the approximate results. Note that every click of **Generate** yields different results, even with the exact same keywords.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Example 1">
|
||||
<p>"Stained Glass"</p>
|
||||
<GridContainer numColumns="4">
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-2D.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-2C.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-2A.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-2B.jpg" />
|
||||
</GridContainer>
|
||||
</TabItem>
|
||||
<TabItem label="Example 2">
|
||||
<p>"Rainbow Pebbles Pile Matte Finish"</p>
|
||||
<GridContainer numColumns="4">
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-1A.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-1B.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-1C.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-1D.jpg" />
|
||||
</GridContainer>
|
||||
</TabItem>
|
||||
<TabItem label="Example 3">
|
||||
<p>"Rusted Metal Charred"</p>
|
||||
<GridContainer numColumns="4">
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-3A.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-3B.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-3C.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-3D.jpg" />
|
||||
</GridContainer>
|
||||
</TabItem>
|
||||
<TabItem label="Example 4">
|
||||
<p>"Japanese Cherry Blossom Fabric"</p>
|
||||
<GridContainer numColumns="4">
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-4C.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-4B.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-4A.jpg" />
|
||||
<img src="../assets/modeling/materials/Material-Generator-Example-4D.jpg" />
|
||||
</GridContainer>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
2. Click a generated image tile to view more options, as well as apply the material in "preview" mode to all selected parts.
|
||||
|
||||
<Grid container spacing={2}>
|
||||
<Grid item><img src="../assets/modeling/materials/Material-Generator-Expanded-Options.png" width="240" /></Grid>
|
||||
<Grid item><img src="../assets/modeling/materials/Material-Generator-Preview-On-Part.jpg" width="540" /></Grid>
|
||||
</Grid>
|
||||
|
||||
3. Adjust the **Studs Per Tile** slider to interactively preview how the material's texture will appear on the selected parts. Additionally, test out the **Organic** toggle which makes materials appear less "repetitive" by randomizing the output.
|
||||
|
||||
<figure>
|
||||
<video src="../assets/modeling/materials/Material-Generator-Preview.mp4" controls width="100%" alt="Adjustment of Studs Per Tile value and Organic toggle" />
|
||||
<figcaption>Adjustment of **Studs Per Tile** value and **Organic** toggle</figcaption>
|
||||
</figure>
|
||||
|
||||
4. When ready, choose a **Base Material** to apply that material's [default physical properties](../parts/materials.md#default-physical-properties) to your custom material. Then click the **Save & Apply Variant** button to save the custom material to the [Material Manager](../parts/materials.md#material-manager).
|
||||
|
||||
## Best practices
|
||||
|
||||
Generating satisfying materials can be an iterative process requiring a longer list of descriptors to help focus in on the material you want. Here are some tips:
|
||||
|
||||
- For close-up patterns, try using terms like "close up," "top down," and "texture."
|
||||
- For simpler repeating patterns, try using terms like "simple," "pattern," "symmetrical," and "flat."
|
||||
- For more control, add stylistic terms like "photorealistic," "cartoon," or "hand-drawn."
|
||||
- For the ability to change colors, try including terms like "grayscale" which will allow you to tint the material afterwards.
|
||||
217
.cursor/rules/roblox/en-us/studio/optimization/memory-usage.md
Normal file
217
.cursor/rules/roblox/en-us/studio/optimization/memory-usage.md
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
---
|
||||
title: Memory usage
|
||||
description: Use Memory and Luau Heap tools within the Developer Console to monitor the memory usage of your experience.
|
||||
---
|
||||
|
||||
import OpeningSteps from '../../includes/developer-console/opening-developer-console.md'
|
||||
|
||||
Every building and scripting component that you add to your experience consumes memory. When memory usage reaches engine limits, the user's device or server may crash, so you need to actively monitor usage.
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/x1JgsC8c8VQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe><br />
|
||||
|
||||
The **Developer Console** provides two tools for monitoring memory usage:
|
||||
|
||||
- [Memory](#memory) — View real-time memory consumption by usage categories, including your custom components and the engine internal processes.
|
||||
|
||||
- [Luau heap](#luau-heap) — Create snapshots of heap memory, which refers to the memory allocation of your scripts. This tool provides several views to help you identify current memory allocation and issues from different perspectives, such as object types and engine classes. It also allows you to create multiple snapshots to compare differences in memory usage over time.
|
||||
|
||||
<OpeningSteps components={props.components}/>
|
||||
|
||||
## Memory
|
||||
|
||||
The **Memory** tool categorizes and displays real-time memory usage. It displays memory usage in MB of each category and generates a chart on usage change over time.
|
||||
|
||||
To view memory allocation:
|
||||
|
||||
1. Open the **Developer Console**.
|
||||
1. Expand the tools dropdown to select **Memory**.
|
||||
|
||||
<img src="../../assets/studio/console/Memory-Open.png" width="200" alt="Dropdown menu of all Developer Console tools with the Memory option highlighted for selection." />
|
||||
|
||||
1. Expand the client-server dropdown to select **Client** or **Server**.
|
||||
1. Browse the memory usage categories and items. If you want to see usage over time, expand the category to display a chart.
|
||||
|
||||
- **CoreMemory** — Memory usage by the core building processes of the engine, including networking, avatars, and GUI elements that you don't have direct control over.
|
||||
- **PlaceMemory** — Memory usage based on how you build your experience, including models, terrain, parts, scripts, and all other custom elements that you add to your experience.
|
||||
|
||||
<BaseAccordion>
|
||||
<AccordionSummary>
|
||||
<Typography variant="h6">PlaceMemory reference</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**HttpCache**</td>
|
||||
<td>Assets (images, meshes, etc.) loaded from Roblox servers and now held in a cache in memory.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Instances**</td>
|
||||
<td>`Class.Instance|Instances` in the place.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Signals**</td>
|
||||
<td>Signals that fire between instances (an event firing on one instance to trigger an event on another instance).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**LuaHeap**</td>
|
||||
<td>Heap memory for both core scripts (scripts that ship with the Roblox client) and custom scripts.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Script**</td>
|
||||
<td>Luau scripts.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**PhysicsCollision**</td>
|
||||
<td>Collision data for physics simulations.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**PhysicsParts**</td>
|
||||
<td>Physics geometry and kinetics.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**GraphicsSolidModels**</td>
|
||||
<td>Graphics data to render solid models.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**GraphicsMeshParts**</td>
|
||||
<td>Graphics for `Class.MeshPart` objects.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**GraphicsParticles**</td>
|
||||
<td>Graphics for particle systems.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**GraphicsParts**</td>
|
||||
<td>Graphics for parts.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**GraphicsSpatialHash**</td>
|
||||
<td>General rendering.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**GraphicsTerrain**</td>
|
||||
<td>Graphics for terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**GraphicsTexture**</td>
|
||||
<td>Texture memory.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**GraphicsTextureCharacter**</td>
|
||||
<td>Texture memory for characters.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Sounds**</td>
|
||||
<td>In-memory sounds.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**StreamingSounds**</td>
|
||||
<td>Streaming sounds.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**TerrainVoxels**</td>
|
||||
<td>Terrain voxels.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**TerrainPhysics**</td>
|
||||
<td>Terrain physics.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Gui**</td>
|
||||
<td>Memory used by common GUI elements.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Animation**</td>
|
||||
<td>Memory used for animation data, such as poses and `Class.KeyframeSequence` cached data for avatar animations.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Navigation**</td>
|
||||
<td>Memory used by supporting structures for `Class.PathfindingService`.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</AccordionDetails>
|
||||
</BaseAccordion>
|
||||
|
||||
- **UntrackedMemory** — Memory allocations that the system can't easily attribute to a particular source.
|
||||
- **PlaceScriptMemory** — Memory usage of your scripts with insights into how individual scripts and custom memory tags contribute to overall memory usage.
|
||||
- **CoreScriptMemory** — Memory usage by internal engine scripts that you don't have direct control over.
|
||||
|
||||
Among these categories, **PlaceMemory** and **PlaceScriptMemory** are the most important ones for performance optimization, because they help you understand how your building and scripting choices affect memory consumption and potential areas for optimization. For more insights into **PlaceScriptMemory**, use the [Luau heap](#luau-heap) tool to create snapshots and analyze memory allocation by different metrics.
|
||||
|
||||
<Alert severity="info">
|
||||
For more information on common memory usage problems and best practices, see [Performance Optimization](../../performance-optimization/improve.md#memory-usage).
|
||||
</Alert>
|
||||
|
||||
## Luau heap
|
||||
|
||||
The **Luau heap** tool allows you to create snapshots of the current allocation of heap memory, which refers to the memory Luau scripts use to store variables, tables, functions, and other runtime data structures. This tool provides several views to help you identify issues from different perspectives, such as object types and engine classes. It also allows you to create multiple snapshots to compare differences in memory usage over time.
|
||||
|
||||
### Create snapshots
|
||||
|
||||
To create a snapshot of your memory allocation:
|
||||
|
||||
1. Open the **Developer Console**.
|
||||
1. Expand the tools dropdown to select **LuauHeap**.
|
||||
|
||||
<img src="../../assets/studio/console/LuauHeap-Open.png" width="200" alt="Dropdown menu of all Developer Console tools with the LuauHeap option highlighted for selection." />
|
||||
|
||||
1. Expand the client-server dropdown to select **Client** or **Server**.
|
||||
1. Click the **Create Snapshot** button.
|
||||
|
||||
### Analyze memory usage
|
||||
|
||||
The tool provides many views into Luau memory usage:
|
||||
|
||||
- **Graph** — Shows an aggregated memory usage tree, with each node representing an object with memory allocated.
|
||||
- **Object Tags** — Shows memory sizes and counts by runtime types, such as `function`, `table`, and `thread`.
|
||||
- **Memory Categories** — Shows memory sizes and counts by engine-assigned memory categories. The engine assigns a memory category to an object at allocation time.
|
||||
- **Object Classes** — Shows memory sizes and counts by engine classes that your scripts use and store their instances, such as `EnumItem`, `Animation`, `CFrame`. Critically, this view does not show memory usage within the engine itself, only the Luau VM.
|
||||
- **Unique References** and **Unparented Instances** — Shows counts and total numbers of instances for **unique references** or **all remaining references** that don't have a parent in the data model and are only reachable by scripts. Also shows all paths that pin the instance object.
|
||||
|
||||
#### Graph
|
||||
|
||||
The **Graph** view is the most detailed and complex view among all Luau heap views. It shows an aggregated memory usage tree with each node representing an object with memory allocated. The tree shows how objects connect to each other and derives the shortest path between object references. It has the following columns of memory size:
|
||||
|
||||
- Size — The self memory usage plus the memory usage by contents within the data structure.
|
||||
- Self — The memory directly allocated for the data structure itself, excluding the memory usage by any content it contains.
|
||||
|
||||
<Alert severity="info">
|
||||
The graph view displays elements smaller than 2 KB as a single `…` node.
|
||||
</Alert>
|
||||
|
||||
<img src="../../assets/studio/console/Graph-View.jpeg" width="800" alt="An example Graph view" />
|
||||
|
||||
The root of the tree graph is `registry`, which stores all engine and Luau references, such as functions connected to signals or the task library, tables returned by module scripts, and global functions, tables and classes. It usually parents the following common entries:
|
||||
|
||||
- `Module @Path.To.Module` is the table returned by a module script.
|
||||
- `name:123 =Path.To.Module` is a function inside a specified script. Anonymous functions don't have names. The top level node often refers to the global script function. Example: `:1= Workspace.[Username].Animate`.
|
||||
- `upvalue` is a reference for captured functions. See [Capture local scope](../../luau/scope.md#capture) for more information.
|
||||
- `env` refers to the environment of a function. For most cases, it's a table representing the global scope of a script.
|
||||
- `globals` refers to the environment of a thread.
|
||||
- `[key]` represents objects that serve as table keys.
|
||||
- `array` represents an array.
|
||||
- `stack` refers to the array that stores all function locals.
|
||||
- `constants` represents all constant values that functions use.
|
||||
|
||||
#### Memory categories
|
||||
|
||||
The **Memory Categories** view shows memory sizes and counts by memory categories, which the engine assigns to objects at allocation time. By default, the memory category has the same name as the script, or you can assign custom memory category names using the `debug.setmemorycategory` function.
|
||||
|
||||
#### Unique references and unparented instances
|
||||
|
||||
The **Unique References** and **Unparented Instances** views are related. Both show memory usage of instances that don't have a parent in the data model and are only reachable by scripts, along with all paths that pin the instance object. If an instance is only referenced within Luau scripts, it appears under **Unique References**. Otherwise, it's also in use by Roblox systems and appears under **Unparented Instances**. Both views show two metrics:
|
||||
|
||||
- **Count** — The number of instances with the same name that are reachable from the same path, such as multiple instances named `Dragon` in the same table.
|
||||
- **Total Instances** — The total number of objects inside those roots, such as all parts, scripts, and sound objects that construct a `Dragon` instance.
|
||||
|
||||
<img src="../../assets/studio/console/Unique-Reference-View.jpeg" width="800" alt="An example Unique Reference view" />
|
||||
|
||||
These views are useful for identifying unnecessary connected instances, which you need to disconnect when you no longer need them. If you see many unexpected instances in this view, check out the paths holding them and evaluate whether they are necessary.
|
||||
169
.cursor/rules/roblox/en-us/studio/optimization/scriptprofiler.md
Normal file
169
.cursor/rules/roblox/en-us/studio/optimization/scriptprofiler.md
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
---
|
||||
title: Script Profiler
|
||||
description: Script Profiler is a tool within the Developer Console that records profiling sessions of all running scripts.
|
||||
---
|
||||
|
||||
**Script Profiler** is a tool within the [Developer Console](../../studio/developer-console.md) that allows you to record profiling sessions of all running scripts and view their CPU time costs with custom recording and display settings. It can record all types of function calls, including Luau functions, method calls, and property accesses. This tool is helpful for identifying scripts that take up the most CPU resources and slow down the performance.
|
||||
|
||||
<Alert severity="info">
|
||||
Script Profiler only records function calls that consume CPU resources, so it doesn't record threads that sleep or wait for results.
|
||||
</Alert>
|
||||
|
||||
## Record profiling sessions
|
||||
|
||||
Before recording, you need to select the recording environment from:
|
||||
|
||||
- **Client** (Default) — Records client-side scripts, including `Class.LocalScript|LocalScripts` and `Class.Script|Scripts` with `Class.BaseScript.RunContext|RunContext` set to `Enum.RunContext.Client|Client`.
|
||||
- **Server** — Records server-side scripts, including `Class.Script|Scripts` with `Class.BaseScript.RunContext|RunContext` set to `Enum.RunContext.Server|Server` or `Enum.RunContext.Legacy|Legacy`. Script Profiler clears all collected server-side data at the end of each session.
|
||||
|
||||
You can also set the following recording options:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Behavior</th>
|
||||
<th>Options</th>
|
||||
<th>Default</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Frequency</td>
|
||||
<td>1000 times per second (1 KHz)<br></br>10,000 times per second (10 KHz)</td>
|
||||
<td>1 KHz</td>
|
||||
<td>The 10 KHz frequency has higher precision, as Script Profiler might not pick up API calls that execute more frequently than your selected frequency, but it also has a higher performance cost.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Session Length</td>
|
||||
<td>1-minute<br></br>5-minute<br></br>10-minute<br></br>Manual</td>
|
||||
<td>Manual</td>
|
||||
<td>The manual option requires you to stop recording manually.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Live Polling Behavior</td>
|
||||
<td>On<br></br>Off</td>
|
||||
<td>Off</td>
|
||||
<td>This behavior polls and refreshes profiling data each second during a profiling session.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
To record a new profiling session:
|
||||
|
||||
1. Open [Developer Console](../../studio/developer-console.md#opening-the-developer-console).
|
||||
2. Expand the tools dropdown to select **ScriptProfiler**.
|
||||
|
||||
<img src="../../assets/studio/console/ScriptProfiler-Open.png" width="200" alt="Dropdown menu of all Developer Console tools with the ScriptProfiler option highlighted for selection." />
|
||||
|
||||
3. Expand the client-server dropdown to select **Client** or **Server**.
|
||||
|
||||
<img src="../../assets/studio/console/Client-Server-Dropdown.png" width="600" alt="Dropdown menu with Client and Server options for selection." />
|
||||
4. (Optional) Check the **Live** checkbox to enable the live polling behavior.
|
||||
5. (Optional) Select **Freq** and **Time** to choose the recording frequency and session time length if you don't want to use the default values.
|
||||
6. Click **Start** to begin the profiling session. If you set a duration, Script Profiler displays a countdown timer with the remaining time in the session.
|
||||
7. Click **Stop** or wait until the recording finishes to display the profiling data.
|
||||
|
||||
## Read profiling data
|
||||
|
||||
After a session stops, Script Profiler generates a table showing how much time each function call costs in CPU time. The table sorts function calls from the most-time-spent to least-time-spent, and allows you to search for specific functions by their name. It provides the following two views:
|
||||
|
||||
- **Callgraph** (Default): Categorizes and displays function calls into a tree structure based on frame tasks. This view displays each task category as nodes under the same root and allows you to expand them to view functions. You can also hover over any node in the tree to view file and line information. For example, **Stepped/CameraInput/<anonymous>** might reveal `Players.[LocalPlayer].PlayerScripts.PlayerModule.CameraModule.CameraInput:125`.
|
||||
<img src="../../assets/studio/console/Callgraph.jpeg" width="800" alt="Example callgraph view of a profiling session." />
|
||||
- **Functions**: Lists all functions without categorizing them by tasks.
|
||||
<img src="../../assets/studio/console/Functions.jpeg" width="800" alt="Example functions view of a profiling session." />
|
||||
|
||||
You can also select from the following display options to tailor your debugging needs:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Options</th>
|
||||
<th>Default</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Unit</td>
|
||||
<td>Milliseconds (ms)<br></br>Percentage (%)</td>
|
||||
<td>ms</td>
|
||||
<td>Displays time spent on each API call in milliseconds or percentages of the total recording session.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Average</td>
|
||||
<td>Off<br></br>1-second<br></br>1-minute<br></br>5-minute<br></br>10-minute</td>
|
||||
<td>Off</td>
|
||||
<td>Calculates the average time spent on each API call by the selected value. If you select an option that is longer than the session length, Script profiler extrapolates the session length to calculate the average. For example, you can select the 5-minute option for a 1-minute session to see the expected average value if you run the code for 5 minutes.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Export profiling data
|
||||
|
||||
Script Profiler allows you to export recorded profiling data as a JSON file. To export recorded data after a profiling session:
|
||||
|
||||
1. On the Script Profiler window, click **Export**.
|
||||
2. On the export window, select the profiling session that you want to export. Rename the default file name if you want to set a custom name.
|
||||
3. Click **Export** to save the JSON file.
|
||||
|
||||
<img src="../../assets/studio/console/Export-Window.jpeg" width="600" alt="Example export window." />
|
||||
|
||||
The exported JSON file includes the following fields:
|
||||
|
||||
- **Version**: The version number.
|
||||
- **SessionStartTime**: A timestamp in milliseconds that records the session start time.
|
||||
- **SessionEndTime**: A timestamp in milliseconds that records the session end time.
|
||||
- **Categories**: An array of frame task categories recorded in the profiling session. Each entry includes:
|
||||
- **Name**: The name of each frame task category.
|
||||
- **NodeId**: The unique identifier of a task category (node). It's a 1-based index into the `Nodes` array. For example, you can look up the node with the `NodeId` of `123` by retrieving the 123rd element in `Nodes`.
|
||||
- **Nodes**: An array of nodes recorded in the profiling session. Each entry includes:
|
||||
- **TotalDuration**: The amount of time that the node costs in CPU time in microseconds.
|
||||
- **FunctionIds**: An array of unique identifiers of functions.
|
||||
- **NodeIds**: An array of Node IDs.
|
||||
- **Functions**: An array of functions recorded in the profiling session.
|
||||
- **TotalDuration**: The amount of time that the function costs in CPU time in microseconds.
|
||||
- **Name**: The name of the function, if available.
|
||||
- **Source**: The source of the function, if available.
|
||||
- **Line**: The line number of the function, if available.
|
||||
- **Flags**: A bit field that indicates any specific function execution environment. Currently can have the following values:
|
||||
- `0`: The 0th bit represents `IsNative` for execution under Native CodeGen.
|
||||
- `1`: The 1 th bit represents `IsPlugin` for execution as part of a plugin.
|
||||
|
||||
```json title="Example Exported Profiling Data"
|
||||
{
|
||||
"Version":2,
|
||||
"SessionStartTime":1704850750514,
|
||||
"SessionEndTime":1704850751198,
|
||||
"Categories":
|
||||
[
|
||||
{"Name":"Parallel Luau","NodeId":4},
|
||||
{"Name":"Heartbeat","NodeId":1}
|
||||
],
|
||||
"Nodes":
|
||||
[
|
||||
{"TotalDuration":2530,"FunctionIds":[1],"NodeIds":[2]},
|
||||
{"TotalDuration":2530,"FunctionIds":[2,5],"NodeIds":[3,7]},
|
||||
{"TotalDuration":1267},
|
||||
{"TotalDuration":7746,"FunctionIds":[3],"NodeIds":[5]},
|
||||
{"TotalDuration":7746,"FunctionIds":[4],"NodeIds":[6]},
|
||||
{"TotalDuration":7746},
|
||||
{"TotalDuration":1263,"FunctionIds":[6],"NodeIds":[8]},
|
||||
{"TotalDuration":1263,"FunctionIds":[7],"NodeIds":[9]},
|
||||
{"TotalDuration":1263,"FunctionIds":[8],"NodeIds":[10]},
|
||||
{"TotalDuration":1263}
|
||||
],
|
||||
"Functions":
|
||||
[
|
||||
{"Name":"main","TotalDuration":2530},
|
||||
{"Source":"builtin_ManageCollaborators.rbxm.ManageCollaborators.Packages._Index.roblox_rodux-3.0.0.rodux.Store","Line":81,"TotalDuration":1267},
|
||||
{"Name":"Script","TotalDuration":7746},
|
||||
{"Source":"Workspace.Actor.Script","Line":1,"TotalDuration":7746},
|
||||
{"Source":"builtin_DeveloperInspector.rbxm.DeveloperInspector.Packages._Index.DeveloperFramework.DeveloperFramework.UI.Components.Grid","Line":221,"TotalDuration":1263},
|
||||
{"Source":"builtin_DeveloperInspector.rbxm.DeveloperInspector.Packages._Index.DeveloperFramework.DeveloperFramework.UI.Components.Grid","Name":"_update","Line":236,"TotalDuration":1263},
|
||||
{"Source":"builtin_DeveloperInspector.rbxm.DeveloperInspector.Packages._Index.DeveloperFramework.DeveloperFramework.UI.Components.Grid","Name":"_getRange","Line":277,"TotalDuration":1263},
|
||||
{"Source":"[C]","Name":"ScrollingFrame.CanvasPosition","TotalDuration":1263}
|
||||
]
|
||||
}
|
||||
```
|
||||
41
.cursor/rules/roblox/en-us/studio/output.md
Normal file
41
.cursor/rules/roblox/en-us/studio/output.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
title: Output
|
||||
description: The Output window in Roblox Studio displays error messages, calls to print(), and calls to warn().
|
||||
---
|
||||
|
||||
The **Output** window, accessible from Studio's **Window** menu or **Script** tab toolbar, displays errors captured from running scripts, messages from Roblox Engine, messages from calls to `print()`, and errors from calls to `warn()`.
|
||||
|
||||
Plugins can interact with the **Output** window through `Class.LogService` which can record and clear the window's contents. You can customize the output through the following elements:
|
||||
|
||||
<img src="../assets/studio/general/Output-Window-Diagram.png" width="820" alt="Sections of Output window indicated by lettered pointers" />
|
||||
|
||||
<Grid container spacing={2}>
|
||||
<Grid item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Box-Label-A.png" width="40" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Filters output by type, such as **Error** or **Warning**.
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Box-Label-B.png" width="40" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Filters output by context, such as **Client**, **Server**, or **User Plugin**.
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Box-Label-C.png" width="40" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Filters output by the text entered into the field, such as an object name.
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Box-Label-D.png" width="40" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Clears all output messages from the window. This action has a shortcut of <kbd>Ctrl</kbd><kbd>K</kbd> on Windows or <kbd>⌘</kbd><kbd>K</kbd> on Mac.
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Box-Label-E.png" width="40" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Controls the level of detail displayed for each output message.<ul><li>**Show Timestamp** — Shows a detailed timestamp in `HH:MM:SS.SSS` format.</li><li>**Show Context** — Shows the message context, such as **Client** or **Server**.</li><li>**Show Source** — If applicable, shows the associated script name and line number.</li><li>**Show Tables Expanded by Default** — For outputted tables, contents are expanded by default.</li><li>**Show Memory Address for Expandable Tables** — For expandable tables, shows the internal memory address, such as `0xb4f0417581144ec5`.</li><li>**Log Mode** — Simplifies output by removing options, such as expandable trees.</li></ul>
|
||||
</Grid>
|
||||
</Grid>
|
||||
156
.cursor/rules/roblox/en-us/studio/pivot-tools.md
Normal file
156
.cursor/rules/roblox/en-us/studio/pivot-tools.md
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
---
|
||||
title: Pivot tools
|
||||
description: Pivot tools and properties give you full control over the points around which objects rotate and translate.
|
||||
---
|
||||
|
||||
The **pivot** tools and related properties give you full control over the points around which objects rotate and translate.
|
||||
|
||||
## Interactive Studio tools
|
||||
|
||||
The interactive Studio tools are located in the **Model** tab toolbar.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Pivot.png" width="800" alt="Pivot tool highlighted in Studio's toolbar." />
|
||||
|
||||
When **Pivot** is toggled on, you can move or rotate the pivot point of a [part](../parts/index.md) or [model](../parts/models.md). Once set, rotation and scaling occur around the pivot point. For more information, see [setting a primary part](../parts/models.md#set-a-primary-part).
|
||||
|
||||
The following diagrams show example pivot locations in relation to object bounds.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Center">
|
||||
<img src="../assets/studio/pivot-tools/Edit-Pivot-Center-A.jpg" width="720" height="405" alt="A blue cube with its pivot point set in the center of the cube. A green circle represents the object's rotation in relation to its pivot point." />
|
||||
</TabItem>
|
||||
<TabItem label="Corner">
|
||||
<img src="../assets/studio/pivot-tools/Edit-Pivot-Corner-A.jpg" width="720" height="405" alt="A blue cube with its pivot point set on a corner of the cube. A green circle represents the object's rotation in relation to its pivot point." />
|
||||
</TabItem>
|
||||
<TabItem label="Outside Object Bounds">
|
||||
<img src="../assets/studio/pivot-tools/Edit-Pivot-Outside-A.jpg" width="720" height="405" alt="A blue cube with its pivot point set on outside of the cube's geometry. A green circle represents the object's rotation in relation to its pivot point." />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
When you rotate the pivot of a [model](../parts/models.md), the bounding box of the model also rotates.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Orientation = (0, 90, 0)">
|
||||
<img src="../assets/studio/pivot-tools/Edit-Pivot-Model-A.jpg" width="720" height="405" alt="A model of a purple, blue, and red block with its pivot point set on a the edge of the model's bounding box. A green circle represents the object's rotation in relation to its pivot point." />
|
||||
</TabItem>
|
||||
<TabItem label="Orientation = (0, 135, 0)">
|
||||
<img src="../assets/studio/pivot-tools/Edit-Pivot-Model-B.jpg" width="720" height="405" />
|
||||
</TabItem>
|
||||
<TabItem label="Orientation = (0, 180, 0)">
|
||||
<img src="../assets/studio/pivot-tools/Edit-Pivot-Model-C.jpg" width="720" height="405" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You can specify a `Class.Model.PrimaryPart|PrimaryPart` for models, which is a `Class.BasePart` within the model that you can use as a positional basis. In terms of pivot points:
|
||||
|
||||
<ol type="A">
|
||||
<li>When you assign a `Class.Model.PrimaryPart|PrimaryPart` to a model, the existing pivot changes to the pivot point of the `Class.Model.PrimaryPart|PrimaryPart`. If you later unassign/clear the `Class.Model.PrimaryPart|PrimaryPart`, the pivot point resets to the **center** of the model's bounding box.</li>
|
||||
<li>If you **delete** the `Class.Model.PrimaryPart|PrimaryPart` from a model, the pivot point remains in the same location and does **not** revert to its previous position. This prevents a sudden "jump" if you delete any parts from the model.</li>
|
||||
</ol>
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Initial Pivot Point">
|
||||
<img src="../assets/studio/pivot-tools/PrimaryPart-1.jpg" width="720" height="405" />
|
||||
</TabItem>
|
||||
<TabItem label="A. PrimaryPart Assigned">
|
||||
<img src="../assets/studio/pivot-tools/PrimaryPart-2.jpg" width="720" height="405" />
|
||||
</TabItem>
|
||||
<TabItem label="B. PrimaryPart Deleted">
|
||||
<img src="../assets/studio/pivot-tools/PrimaryPart-3.jpg" width="720" height="405" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Snap
|
||||
|
||||
The **Snap** checkbox, available by click‑holding the small corner arrow on the **Pivot** button, toggles whether the pivot point snaps to **hotspots** such as corners, edges, or centers when you move it with the **Edit Pivot** tool. When snapping is enabled, hotspots display as small magenta points.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<img src="../assets/studio/pivot-tools/Hotspots-Part.jpg" />
|
||||
<figcaption>Hotspots on a part</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="../assets/studio/pivot-tools/Hotspots-Model.jpg" />
|
||||
<figcaption>Hotspots on a model</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
### Reset
|
||||
|
||||
The **Reset** button moves the pivot point to the **center** of an object or model's bounding box. This operation is useful after you've changed the composition of a model and wish to place its pivot point at the center of its new bounding box.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Pivot-Reset.png" width="800" alt="Pivot Reset tool highlighted in Studio's toolbar." />
|
||||
|
||||
## Pivot properties
|
||||
|
||||
In addition to the interactive tools, pivot values can be directly set in the [Properties](../studio/properties.md) window.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Property</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Origin Position**</td>
|
||||
<td>Current world location of the object based on its pivot point rather than its bounding box. Useful for setting the precise location of a `Class.Model`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Origin Orientation**</td>
|
||||
<td>Current orientation of the object based around its pivot point rather than its bounding box.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Pivot Offset Position**</td>
|
||||
<td>Precise location of the pivot relative to the object.¹</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Pivot Offset Orientation**</td>
|
||||
<td>Precise pivot orientation.¹</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**World Pivot Position**</td>
|
||||
<td>The precise world location of the pivot for `Class.Model|Models` without a `Class.Model.PrimaryPart|PrimaryPart`. If a `Class.Model.PrimaryPart|PrimaryPart` is set, the model will use **Pivot Offset Position** since the pivot becomes relative to that part.¹</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**World Pivot Orientation**</td>
|
||||
<td>The precise world orientation for `Class.Model|Models` without a `Class.Model.PrimaryPart|PrimaryPart`. If a `Class.Model.PrimaryPart|PrimaryPart` is set, the model will use **Pivot Offset Orientation** since the pivot becomes relative to that part.¹</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<figcaption><sup>1</sup> Changing this property will not move or rotate the object.</figcaption>
|
||||
|
||||
## Manipulate pivots in scripts
|
||||
|
||||
Beyond the Studio tools, pivot points can be accessed and manipulated in scripts.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Function or Property</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>`Class.PVInstance:GetPivot()|GetPivot()`</td>
|
||||
<td>Queries the current world location of an object's pivot as a `Datatype.CFrame`. This returns an object's position in 3D space regardless of whether it's an individual part or a `Class.Model`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Class.PVInstance:PivotTo()|PivotTo()`</td>
|
||||
<td>Moves the object such that its pivot will be located at the specified `Datatype.CFrame`. This allows for uniform object movement of both individual parts and models.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Class.BasePart.PivotOffset`</td>
|
||||
<td>The `Datatype.CFrame` which specifies the pivot offset; effectively the offset of the pivot from the `Datatype.CFrame` of the `Class.BasePart`.²</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Class.BasePart.PivotOffset|Model.WorldPivot`</td>
|
||||
<td>For `Class.Model|Models` without a `Class.Model.PrimaryPart|PrimaryPart`, the `Datatype.CFrame` which specifies the model's pivot in world space. If a `Class.Model.PrimaryPart|PrimaryPart` is set, the model will use `Class.BasePart.PivotOffset` since the pivot becomes relative to that part.²</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<figcaption><sup>2</sup> Changing this property will not move or rotate the object.</figcaption>
|
||||
154
.cursor/rules/roblox/en-us/studio/plugins.md
Normal file
154
.cursor/rules/roblox/en-us/studio/plugins.md
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
---
|
||||
title: Studio plugins
|
||||
description: Explains how to create, publish, and monetize extensions to Studio that add custom functionality.
|
||||
---
|
||||
|
||||
A **plugin** is an extension that adds additional features or functionality to Studio. You can [install](../production/creator-store.md#find-assets) community-made plugins from the Creator Store, or you can [create](#create-new-plugins) and [publish](#upload-distribute-and-monetize-plugins) your own to the [Toolbox](../projects/assets/toolbox.md) to use across your experiences.
|
||||
|
||||
If you choose to also distribute your plugins to the Creator Store, you can either offer them for free or sell them for **United States Dollars**. Roblox offers a market-leading revenue share for these sales, as only taxes and payment processing fees are deducted. For more information on selling plugins, see [Selling on the Creator Store](../production/sell-on-creator-store.md).
|
||||
|
||||
## Create new plugins
|
||||
|
||||
You can create your own plugins to improve your workflow in Studio. The following code sample is a plugin called **AddEmptyScript** that inserts an empty script as the child of an object or in `Class.ServerScriptService`. The following sections explain the major parts to creating this plugin.
|
||||
|
||||
To begin, you should enable **Plugin Debugging Enabled** in the **Studio** section of Studio's settings. This will expose the `Class.PluginDebugService` in Studio which provides real-time debugging for your plugin's code and makes it easier to reload and save your plugin.
|
||||
|
||||
```lua title="AddEmptyScript Plugin"
|
||||
local ChangeHistoryService = game:GetService("ChangeHistoryService")
|
||||
local Selection = game:GetService("Selection")
|
||||
local ServerScriptService = game:GetService("ServerScriptService")
|
||||
|
||||
-- Create a new toolbar section and Plugins menu folder titled "Custom"
|
||||
local toolbar = plugin:CreateToolbar("Custom")
|
||||
|
||||
-- Add a toolbar button labeled "Empty Script"
|
||||
local newScriptButton = toolbar:CreateButton("Empty Script", "Create an empty script", "rbxassetid://14978048121")
|
||||
|
||||
-- Make button clickable even if 3D viewport is hidden
|
||||
newScriptButton.ClickableWhenViewportHidden = true
|
||||
|
||||
local function onPluginButtonClicked()
|
||||
local selectedObjects = Selection:Get()
|
||||
local parent = ServerScriptService
|
||||
if #selectedObjects > 0 then
|
||||
parent = selectedObjects[1]
|
||||
end
|
||||
|
||||
local newScript = Instance.new("Script")
|
||||
newScript.Source = ""
|
||||
newScript.Parent = parent
|
||||
ChangeHistoryService:SetWaypoint("Added new empty script")
|
||||
end
|
||||
|
||||
newScriptButton.Click:Connect(onPluginButtonClicked)
|
||||
```
|
||||
|
||||
### Save plugin script
|
||||
|
||||
To create a plugin, first create a `Class.Script` and save it locally.
|
||||
|
||||
1. Insert a new `Class.Script` inside `Class.ServerStorage` and rename it to **AddEmptyScript**.
|
||||
|
||||
<img src="../assets/studio/explorer/Plugin-Empty-Script-Adder.png" width="320" />
|
||||
|
||||
2. Copy and paste the **AddEmptyScript Plugin** code into the new script.
|
||||
3. With the new script selected in the **Explorer** window, select **Save as Local Plugin** from Studio's **Plugins** menu.
|
||||
4. In the popup window, click **Save** to insert the plugin script into your local **Plugins** folder of the Studio installation.
|
||||
5. The plugin should appear in `Class.PluginDebugService` and start running.
|
||||
6. <Chip label="IMPORTANT" size="small" variant="outlined" color="warning" /> Delete the original script in `Class.ServerStorage` and work from the `AddEmptyScript` plugin inside `Class.PluginDebugService`, otherwise you may end up applying changes to the wrong script.
|
||||
|
||||
<img src="../assets/studio/explorer/Plugin-Created.png" width="320" />
|
||||
|
||||
<Alert severity="info">
|
||||
To update a specific plugin within `Class.PluginDebugService`, right‑click it and select **Save and Reload Plugin** from the context menu. If you simply want to reload the plugin, for example to step through a section of code using a breakpoint without saving the plugin, right‑click it and select **Reload Plugin**.
|
||||
|
||||
At the broadest level, you can also update **all** plugins by right-clicking `Class.PluginDebugService` and selecting **Save and Reload All Plugins in Debugger** (shortcut <kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>L</kbd> or <kbd>⌘</kbd><kbd>Shift</kbd><kbd>L</kbd>).
|
||||
</Alert>
|
||||
|
||||
### Add toolbar button
|
||||
|
||||
To add a button for your plugin to the **Plugins** tab of the Studio toolbar, use the `Class.Plugin:CreateToolbar()` and `Class.PluginToolbar:CreateButton()` methods. In the code for **AddEmptyScript**, line 5 creates a new section in the toolbar and **Plugins** menu folder titled **Custom**, while line 8 creates a button labeled **Empty Script**.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Custom-Plugin-Button.png" width="800" alt="New plugin button added to toolbar in Studio" />
|
||||
|
||||
### Execute code on click
|
||||
|
||||
To make the plugin execute code when a user clicks the toolbar button, connect a function to the button's `Class.PluginToolbarButton.Click` event. In the code for **AddEmptyScript**, the connecting function is `onPluginButtonClicked()`.
|
||||
|
||||
### Check user selection
|
||||
|
||||
To modify a plugin's behavior based on what the user has selected, use the `Class.Selection` service. The `onPluginButtonClicked()` function checks if the user has anything selected and creates the new script as its child instead of inside `Class.ServerScriptService`. If the user doesn't have anything selected, it creates the new script in `Class.ServerScriptService`.
|
||||
|
||||
<img src="../assets/studio/explorer/Plugin-Inserted-Script.png" width="320" />
|
||||
|
||||
### Support undo and redo
|
||||
|
||||
Use `Class.ChangeHistoryService` to allow users to undo and redo changes made by a plugin within an experience. In your script, set the plugin to call `Class.ChangeHistoryService:TryBeginRecording()` and store the identifier assigned to the API call before making changes. Then set the plugin to call `Class.ChangeHistoryService:FinishRecording()` after making changes, so it captures any changes made during the recording session for undo and redo.
|
||||
|
||||
The following code sample creates an example plugin that can apply the neon material to selected parts. It uses `Class.ChangeHistoryService` to record and manage the changes made by the plugin:
|
||||
|
||||
```lua title="Example Material Plugin with Recordings for Undo and Redo"
|
||||
local ChangeHistoryService = game:GetService("ChangeHistoryService")
|
||||
local Selection = game:GetService("Selection")
|
||||
|
||||
-- Create an example plugin
|
||||
local toolbar = plugin:CreateToolbar("Example Plugin")
|
||||
local button = toolbar:CreateButton("Neon it up", "", "")
|
||||
|
||||
-- Connect a function to the click event
|
||||
button.Click:Connect(function()
|
||||
local parts = {}
|
||||
for _, part in Selection:Get() do
|
||||
if part:IsA("BasePart") then
|
||||
parts[#parts + 1] = part
|
||||
end
|
||||
end
|
||||
if #parts < 1 then
|
||||
-- Nothing to do!
|
||||
return
|
||||
end
|
||||
|
||||
-- Try to begin a recording with a specific identifier
|
||||
local recording = ChangeHistoryService:TryBeginRecording("Set selection to neon")
|
||||
|
||||
-- Check if recording was successfully initiated
|
||||
if not recording then
|
||||
-- This indicates that your plugin began a previous recording and never completed it
|
||||
-- You may only have one recording per plugin active at a time
|
||||
return
|
||||
end
|
||||
|
||||
-- Iterate through the selected parts
|
||||
for _, part in parts do
|
||||
part.Material = Enum.Material.Neon -- Set the material of the part to Neon
|
||||
end
|
||||
|
||||
-- Finish the recording, committing the changes to the history
|
||||
ChangeHistoryService:FinishRecording(recording, Enum.FinishRecordingOperation.Commit)
|
||||
end)
|
||||
```
|
||||
|
||||
## Upload, distribute, and monetize plugins
|
||||
|
||||
As with [models](../parts/models.md), [meshes](../parts/meshes.md), [images](../parts/textures-decals.md), and [animations](../animation/editor.md#creating-an-animation), you can distribute plugins to Roblox to make them easy to reuse from the [Toolbox](../projects/assets/toolbox.md). You can choose to make them publicly available to all other creators on the [Creator Store](../production/creator-store.md), or to distribute them privately for your own use. If you choose to distribute your plugin publicly, you can set a price at which to sell it to other creators.
|
||||
|
||||
<Alert severity="info">
|
||||
The only way to distribute and set a price for a plugin is through the Creator Dashboard. You can always upload a plugin using this process and, if age-verified, monetize it later from the dashboard. For instructions on this process, see [Distributing Assets](../production/creator-store.md#through-creator-dashboard).
|
||||
</Alert>
|
||||
|
||||
To distribute a plugin:
|
||||
|
||||
1. In the [Explorer](./explorer.md) window, select a plugin script and then select **Publish as Plugin** from Studio's **Plugins** menu.
|
||||
1. <Chip label="OPTIONAL" size="small" variant="outlined" /> In the upper-left corner of the asset configuration window, click the image to upload a 512×512 image.
|
||||
1. Fill in the following fields:
|
||||
|
||||
- **Name** — A title for your plugin.
|
||||
- **Description** — A description that describes what a potential user should expect the plugin to do.
|
||||
- **Creator** — The creator you'd like to attribute as the creator of the plugin.
|
||||
|
||||
1. Click the **Submit** button. Your plugin is now available to you in the **Inventory** and **Creations** tabs of the [Toolbox](../projects/assets/toolbox.md).
|
||||
1. Click the link to Creator Dashboard to [configure distribution](../production/creator-store.md#through-creator-dashboard).
|
||||
|
||||
<Alert severity="info">
|
||||
To publicly distribute or monetize a plugin you have previously uploaded, use the [Creations](https://create.roblox.com/dashboard/creations?activeTab=Model) section of the Creator Dashboard. For more information, see [Distributing Assets](../production/creator-store.md).
|
||||
</Alert>
|
||||
147
.cursor/rules/roblox/en-us/studio/properties.md
Normal file
147
.cursor/rules/roblox/en-us/studio/properties.md
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
---
|
||||
title: Properties window
|
||||
description: The Properties window lets you adjust properties of a selected object to change how it looks and behaves.
|
||||
---
|
||||
|
||||
The **Properties** window, accessible from Studio's **Window** menu or **Home** tab toolbar, allows you to adjust certain properties of a selected object to change how the object looks and behaves. Additionally, you can manage [tags](#instance-tags) and configure instance [attributes](#instance-attributes) at the bottom of the window.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Properties.png" width="800" alt="Properties highlighted in Studio's toolbar." />
|
||||
|
||||
When you select an object, the window's header bar changes to reflect the object's class and name, and its properties are divided into sections. For example, a `Class.MeshPart` includes sections like **Appearance** and **Transform** which respectively allow you to change its appearance and transform its `Class.BasePart.Size|Size`, `Class.BasePart.CFrame|CFrame`, and origin.
|
||||
|
||||
<img src="../assets/studio/properties/Sections-Example.png" width="320" />
|
||||
|
||||
<Alert severity="info">
|
||||
You can collapse or expand any section or subsection by clicking the small arrow to the left of its name. After you expand or collapse a section, it remains expanded or collapsed for other objects of the same class, as well as related objects that share the same property grouping.
|
||||
</Alert>
|
||||
|
||||
Some properties are collapsed by default, but you can expand them by clicking the small arrow next to its name. For instance, `Class.BasePart|BaseParts` contain a `Class.BasePart.Position|Position` property which represents an **X**, **Y**, **Z** coordinate in the 3D world. In Studio, these coordinates can be entered in two ways:
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<img src="../assets/studio/properties/Input-Combined.png" width="320" />
|
||||
<figcaption>All three coordinates typed into the parent **Size** field, separated by commas</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="../assets/studio/properties/Input-Expanded.png" width="320" />
|
||||
<figcaption>Property expanded and an individual size vector typed into the **X**, **Y**, and **Z** fields</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
<Alert severity="info">
|
||||
After you expand or collapse a property, it remains expanded or collapsed for other objects of the same class, as well as related objects that share the same property.
|
||||
</Alert>
|
||||
|
||||
## Property filter
|
||||
|
||||
You can filter properties by typing a search query into the **Filter Properties** input near the top of the window. For example, filtering by the letters "velo" finds all properties containing them, such as **AssemblyLinear<u>Velo</u>city** and **AssemblyAngular<u>Velo</u>city**. Quickly access this input by pressing <kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>P</kbd> (Windows) or <kbd>⌘</kbd><kbd>Shift</kbd><kbd>P</kbd> (Mac).
|
||||
|
||||
<img src="../assets/studio/properties/Instance-Filtered.png" width="320" />
|
||||
|
||||
## Instance tags
|
||||
|
||||
The **Tags** section allows you to apply specific tags for use with `Class.CollectionService`. Tags are sets of strings applied to instances that replicate from the server to the client. They are also serialized when places are saved.
|
||||
|
||||
To add tags to an instance through the **Properties** window:
|
||||
|
||||
1. Select the instance, scroll to the **Tags** section, and click the **+** button.
|
||||
|
||||
<img src="../assets/studio/properties/Add-Tag-Button.png" width="320" />
|
||||
|
||||
1. In the popup window, enter a new tag name **or** select a tag you've already created for any other instance from the list below the input field. The tag will appear within the **Tags** section.
|
||||
|
||||
<img src="../assets/studio/properties/Set-Tag.png" width="320" />
|
||||
|
||||
1. If necessary, you can remove an existing tag by clicking the **×** icon.
|
||||
|
||||
<img src="../assets/studio/properties/Remove-Tag-Button.png" width="320" />
|
||||
|
||||
## Instance attributes
|
||||
|
||||
**Attributes** allow you to customize instances with your own data. They are similar to built-in object properties, but you can create and modify your own attributes for any instance. Key features include:
|
||||
|
||||
- Attributes can be created, edited, and deleted directly within Studio or through scripting (see [properties and attributes](../scripting/attributes.md) for script commands to create, set, get, and delete attributes).
|
||||
- Attributes and their values are saved with your place and assets.
|
||||
- Value changes can be viewed in real time and are **replicated** so that clients can access them immediately.
|
||||
|
||||
You can store the following types/values in attributes:
|
||||
|
||||
<Grid container spacing={3}>
|
||||
<Grid item>
|
||||
<ul>
|
||||
<li>[string](../luau/strings.md)</li>
|
||||
<li>[boolean](../luau/booleans.md)</li>
|
||||
<li>[number](../luau/numbers.md)</li>
|
||||
<li>`Datatype.UDim`</li>
|
||||
</ul>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ul>
|
||||
<li>`Datatype.UDim2`</li>
|
||||
<li>`Datatype.BrickColor`</li>
|
||||
<li>`Datatype.Color3`</li>
|
||||
<li>`Datatype.Vector2`</li>
|
||||
</ul>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ul>
|
||||
<li>`Datatype.Vector3`</li>
|
||||
<li>`Datatype.CFrame`</li>
|
||||
<li>`Datatype.NumberSequence`</li>
|
||||
<li>`Datatype.ColorSequence`</li>
|
||||
</ul>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<ul>
|
||||
<li>`Datatype.NumberRange`</li>
|
||||
<li>`Datatype.Rect`</li>
|
||||
<li>`Datatype.Font`</li>
|
||||
</ul>
|
||||
</Grid>
|
||||
</Grid><br />
|
||||
|
||||
New attributes can be created and modified in Studio as follows:
|
||||
|
||||
1. Select the instance, scroll to the **Attributes** section, and click the **+** button.
|
||||
|
||||
<img src="../assets/studio/properties/Add-Attribute-Button.png" width="320" />
|
||||
|
||||
1. In the popup window, enter the attribute **Name**, select its **Type**, and click **Save**.
|
||||
1. The new attribute will appear with a default value that you can change just like any other property.
|
||||
|
||||
<img src="../assets/studio/properties/Set-Attribute.png" width="320" />
|
||||
|
||||
1. If necessary, you can rename or delete an attribute by clicking the gear icon.
|
||||
|
||||
<img src="../assets/studio/properties/Rename-Delete-Attribute-Button.png" width="320" />
|
||||
|
||||
## Configurable defaults
|
||||
|
||||
The **configurable defaults** feature allows you to save properties from a selected `Class.Instance` as the new default for that type, reset them as needed, and share them from a local file if desired. Use cases include:
|
||||
|
||||
- A default `Class.MeshPart` instance where `Class.BasePart.Anchored|Anchored` is `true`, so that every new `Class.MeshPart` inserted into the 3D workspace is anchored.
|
||||
- A set of default [mechanical constraints](../physics/mechanical-constraints.md) with physical behaviors that match the type of mechanisms you're currently building, such as massive vehicles vs. smaller machines with less mass.
|
||||
- A set of default [light](../effects/light-sources.md) sources (`Class.PointLight`, `Class.SpotLight`, `Class.SurfaceLight`), each with `Class.Light.Brightness|Brightness` that suits the environment you're designing.
|
||||
|
||||
To **set** a specific instance as the default:
|
||||
|
||||
1. Select the instance in the 3D viewport or [Explorer](./explorer.md) hierarchy.
|
||||
2. From Studio's main **Edit** menu, select **Save as Default [Instance]**. A toast notification will indicate that the default has been updated, and newly inserted instances of that type will match the default properties.
|
||||
|
||||
<img src="../assets/studio/properties/Default-Properties-Toast.jpg" width="100%" />
|
||||
|
||||
<Alert severity="info">
|
||||
Instance defaults are saved **locally** on each machine to a `DefaultInstances.rbxm` file, not to your Roblox or group account. The location of this directory can be changed in Studio's settings (<kbd>Alt</kbd><kbd>S</kbd> or <kbd>⌥</kbd><kbd>S</kbd>) under the **Studio** tab ⟩ **Instance Defaults Dir**.
|
||||
</Alert>
|
||||
|
||||
To **reset** a configurable default instance:
|
||||
|
||||
1. Select any instance of that type in the 3D viewport or [Explorer](./explorer.md) hierarchy.
|
||||
2. From Studio's main **Edit** menu, select **Reset Default [Instance]**. Existing instances of that type will retain their properties, but newly inserted instances will use Studio's default properties.
|
||||
|
||||
<Alert severity="warning">
|
||||
Note the following exceptions and behavioral rules to default instances:
|
||||
|
||||
- The **positional** instance properties `Class.BasePart.Position`, `Class.BasePart.CFrame`, `Class.PVInstance.Origin`, and `Class.Model.WorldPivot` are **not** affected by default properties, but rather are overridden by Studio insertion rules and workflows. However, `Class.GuiObject.Position` and positional properties for `Class.Attachment|Attachments` (`Class.Attachment.Position|Position`, `Class.Attachment.WorldCFrame|WorldCFrame`, `Class.Attachment.WorldPosition|WorldPosition`) are stored/maintained in configured defaults of those instance types.
|
||||
- Studio's **Group as Model** (<kbd>Ctrl</kbd><kbd>G</kbd> or <kbd>⌘</kbd><kbd>G</kbd>) and **Group as Folder** (<kbd>Ctrl</kbd><kbd>Alt</kbd><kbd>G</kbd> or <kbd>⌘</kbd><kbd>⌥</kbd><kbd>G</kbd>) actions do **not** use the instance defaults for `Class.Model` or `Class.Folder`, respectively.
|
||||
</Alert>
|
||||
20
.cursor/rules/roblox/en-us/studio/rig-builder.md
Normal file
20
.cursor/rules/roblox/en-us/studio/rig-builder.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Rig Generator
|
||||
description: The Rig Generator tool lets you insert pre-built character models.
|
||||
---
|
||||
|
||||
The **Rig Generator** tool lets you quickly insert basic pre-built character rigs into your experience. You can also insert a rig of your account's avatar character, including character customizations and accessories. The tool inserts character `Class.Model|Models` with the appropriate joints and humanoid structure to support [animation](../animation/index.md), [accessories](../art/accessories/index.md), and [character customizations](../characters/appearance.md).
|
||||
|
||||
1. From the toolbar's **Avatar** or **Home** tab, click **Character**.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Character.png" width="800" alt="Character button highlighted in Studio's toolbar." />
|
||||
|
||||
1. From the popup, select from the available options. You can insert either a legacy **R6** rig consisting of 6 mesh objects, or an **R15** rig which consists of 15 mesh objects and significantly expands upon the R6's limited motion range.
|
||||
|
||||
<Alert severity="warning">
|
||||
Note that you can only equip clothing and other layerable accessories to **R15** models.
|
||||
</Alert>
|
||||
|
||||
1. Choose a body shape of either **Masculine** or **Feminine** and then click one of the style buttons. The rig displays both in the 3D viewport and in the [Explorer](../studio/explorer.md) window under the name **Rig**.
|
||||
|
||||
<img src="../assets/studio/explorer/Rig-Hierarchy.png" width="320" />
|
||||
586
.cursor/rules/roblox/en-us/studio/script-editor.md
Normal file
586
.cursor/rules/roblox/en-us/studio/script-editor.md
Normal file
|
|
@ -0,0 +1,586 @@
|
|||
---
|
||||
title: Script Editor
|
||||
description: Roblox's built-in, fully-featured script editor includes modern conveniences like autocomplete, code highlighting, and multi-cursor editing.
|
||||
---
|
||||
|
||||
The **Script Editor** in Studio is the primary tool for scripting on Roblox. It's a self-improving environment that can help you write high-impact code, shorten your development time, and iterate on your experiences. It can improve your scripting experience by:
|
||||
|
||||
- Formatting and highlighting syntax in your code.
|
||||
- Offering ways to [autocomplete](#autocomplete-features) phrases in your code as you type.
|
||||
- Helping you [navigate code](#code-navigation) by jumping to variable and function declarations.
|
||||
- Helping you [find and replace](#find-and-replace) code in open scripts or all scripts.
|
||||
- Providing [real-time feedback](#real-time-feedback) on your code quality and performance.
|
||||
|
||||
The Script Editor supports all types of [scripts](../scripting/index.md) and opens automatically when you create a new script or double-click an existing script in the [Explorer](../studio/explorer.md) window.
|
||||
|
||||
<Alert severity="success">
|
||||
You can [customize](#editor-settings) the Script Editor to suit your preferences and workflows, including font family/size, formatting behavior, and colors for syntax highlighting. You can also toggle features such as [autocomplete](#autocomplete-features), and [script analysis](#script-analysis).
|
||||
</Alert>
|
||||
|
||||
## Autocomplete features
|
||||
|
||||
The Script Editor's autocomplete features generate code-related information that can improve your programming efficiency, such as:
|
||||
|
||||
- **Informed suggestions** on how to complete phrases as you type them that are contextual to the experience's [data model](../projects/data-model.md). For example, if you have a `Class.Model` in `Class.Workspace` called **RocketShip**, autocomplete suggests `RocketShip` when you type `workspace.roc` and indicates that it's a `Class.Model`.
|
||||
|
||||
<img src="../assets/studio/script-editor/Autocomplete-Data-Model.png" width="780" alt="Autocomplete showing suggestions based on the experience's data model" />
|
||||
|
||||
<Alert severity="info">
|
||||
Use the <kbd>↑</kbd> and <kbd>↓</kbd> keys to browse the suggestions, then press <kbd>Tab</kbd> or <kbd>Enter</kbd> to accept a suggestion and insert the complete phrase.
|
||||
</Alert>
|
||||
|
||||
- **Autofill names** for variables and functions that you declare, helping you avoid pesky typos.
|
||||
|
||||
<img src="../assets/studio/script-editor/Autocomplete-Variable.png" width="780" alt="Autocomplete showing suggestions based on a previously declared variable." />
|
||||
|
||||
- **Documentation pop-ups with code samples** that are similar to those on the [Engine API Reference](/reference/engine), giving you context on the API's usage.
|
||||
|
||||
<img src="../assets/studio/script-editor/Autocomplete-API.png" width="780" alt="Autocomplete showing suggestions based on a Roblox Engine API." />
|
||||
|
||||
- **On-hover tooltips** that you can customize with your own defined documentation.
|
||||
|
||||
<img src="../assets/studio/script-editor/Autocomplete-CustomDocs.png" width="780" alt="Autocomplete showing custom documentation." />
|
||||
|
||||
- **On-hover script analysis diagnostics** with information you can use to troubleshoot errors.
|
||||
|
||||
<img src="../assets/studio/script-editor/Autocomplete-Diagnostics.png" width="780" alt="Autocomplete showing diagnostic information." />
|
||||
|
||||
- **Function signatures** when you type an argument, providing you a reference for its parameters and return values.
|
||||
|
||||
<img src="../assets/studio/script-editor/Autocomplete-Signature.png" width="780" alt="Autocomplete showing function signature" />
|
||||
|
||||
## Code navigation
|
||||
|
||||
### Go to declaration
|
||||
|
||||
You can jump to the declaration of a function or variable by holding <kbd>Ctrl</kbd> on Windows or <kbd>⌘</kbd> on Mac when clicking the call, or by right-clicking its call and clicking **Go to Declaration**.
|
||||
|
||||
<img src="../assets/studio/script-editor/Go-To-Declaration.png" width="800" alt="Go to Declaration workflow on a declared function" />
|
||||
|
||||
### Script function filter
|
||||
|
||||
The **Script Function Filter** displays a list of all functions declared in a script. To open it, press <kbd>Alt</kbd><kbd>F</kbd> on Windows or <kbd>⌥</kbd><kbd>F</kbd> on Mac. With the list open, you can browse the signatures for each function, filter through them by name, and double-click one to jump to its declaration.
|
||||
|
||||
<img src="../assets/studio/script-editor/Script-Functions-Filter.png" width="800" alt="Script Function Filter showing all functions inside a script" />
|
||||
|
||||
## Find and replace
|
||||
|
||||
The **Find/Replace** widget lets you find and replace code in an open script. The widget supports matching case, matching the whole word, and searching by regular expressions. To open it, press <kbd>Ctrl</kbd><kbd>F</kbd> on Windows or <kbd>⌘</kbd><kbd>F</kbd> on Mac.
|
||||
|
||||
<img src="../assets/studio/script-editor/Find-Replace-Widget-Labeled.png" width="760" alt="Find/Replace widget labeled"/>
|
||||
|
||||
<Alert severity="info">
|
||||
For broader searches, the **Find All / Replace All** window lets you find/replace code across multiple scripts in the experience. To open it, press <kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>F</kbd> on Windows or <kbd>⌘</kbd><kbd>Shift</kbd><kbd>F</kbd> on Mac.
|
||||
</Alert>
|
||||
|
||||
## Real-time feedback
|
||||
|
||||
### Script Analysis
|
||||
|
||||
The **Script Analysis** window, accessible through the **Analysis** button in Studio's **Script** tab toolbar, performs static analysis on your scripts and displays active errors and warnings. For more information on the errors and warnings, see the [Luau linting](https://luau.org/lint) documentation.
|
||||
|
||||
<figure>
|
||||
<img src="../assets/studio/script-editor/Script-Analysis-1.png" width="800" alt="Script with various marked errors" />
|
||||
<figcaption>Script errors underlined in Script Editor</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="../assets/studio/script-editor/Script-Analysis-2.png" width="800" alt="Script Analysis window with details on marked errors from script" />
|
||||
<figcaption>Errors explained in Script Analysis window</figcaption>
|
||||
</figure>
|
||||
|
||||
### Output
|
||||
|
||||
The [Output](../studio/output.md) window displays errors captured from running scripts, messages from the Roblox engine, messages from calls to `print()`, and errors from calls to `warn()`.
|
||||
|
||||
<img src="../assets/studio/general/Output-Window.png" width="800" />
|
||||
|
||||
## Code Assist
|
||||
|
||||
**Code Assist** is a feature that suggests lines or functions of code as you type, helping you code more efficiently and stay focused. Based on contexts from your comment and code, suggestions will be triggered in two ways:
|
||||
|
||||
- **Automatically** when you pause on a line for a few seconds and the AI model has enough context for a suggestion.
|
||||
- **Manually** with shortcut <kbd>Alt</kbd><kbd>∖</kbd> on Windows or <kbd>⌥</kbd><kbd>∖</kbd> on Mac.
|
||||
|
||||
Press <kbd>Tab</kbd> to accept a suggestion, or ignore it by continuing to type. Currently, your script needs to contain at least a few lines of code to trigger a suggestion.
|
||||
|
||||
<video controls width="800" src="../assets/studio/script-editor/Code-Assist.mp4" alt="Video of Code Assist suggestion tool in Studio's script editor"></video>
|
||||
|
||||
<Alert severity="warning">
|
||||
**Code Assist** helps automate basic coding tasks so you can focus on creative work, but it does not always suggest perfect code (see [Limitations](#limitations)). It's still your responsibility to review, test, and determine if the code suggestion is contextually appropriate.
|
||||
</Alert>
|
||||
|
||||
### Improve suggestions
|
||||
|
||||
To get more accurate and relevant suggestions, it's recommended that you follow clean coding practices, regardless of assistance, and:
|
||||
|
||||
- Break down your code into smaller functions.
|
||||
- Use descriptive script names that capture the overall intent of what each script does. For example, name a script **SyncCustomSounds** instead of just **Sounds**.
|
||||
- Assign descriptive names for parameters, functions, and scripts. For example, name a part **GreenSphere** instead of simply **grs**, or name a function `generateSphere()` instead of `gen()`. Using named functions versus anonymous functions can also produce better hints.
|
||||
- Consistently include well-written [comments](../luau/comments.md) that describe the task you're implementing and what the inputs/outputs should be.
|
||||
- Consider including some sample calls with expected results in comments.
|
||||
- Suggest how to solve a problem, for instance `-- Use raycast`.
|
||||
- Use the exact function or variable name you defined, for example `-- Create 10 greenSphere objects` instead of `-- Create 10 spheres`.
|
||||
- If you're a novice scripter, start with basic projects such as "make the player jump when they touch the part" or use the tool to generate small code snippets that you can expand upon as your knowledge grows.
|
||||
|
||||
### Limitations
|
||||
|
||||
The tool helps automate basic coding tasks but it does not always suggest perfect code. Known limitations include:
|
||||
|
||||
- Manual triggering does not **always** force-generate a suggestion.
|
||||
- Suggestions are machine learned from a corpus of code and can thus reflect some limitations of the code they're trained on. For example, suggestions may not use newer APIs in favor of older APIs, or they may use Lua instead of [Luau](../luau/index.md).
|
||||
- The tool may generate incorrect or misleading information that is not useful for your purpose.
|
||||
- Internal filters attempt to block offensive language, but they're not all-encompassing and there's a possibility the tool may generate offensive or biased information.
|
||||
- The suggestions may be the same, similar, or different among users, even with the same prompts. Your code, however, will never be shared with others.
|
||||
- The suggestion may be incomplete due to the limited length of output from the learning models.
|
||||
- There's a daily cap for the number of suggestions and, once the cap is reached, you will get no suggestions until the next day.
|
||||
|
||||
### Code privacy
|
||||
|
||||
Currently, Roblox does not use any non-public data to train the learning models. The tool only uses a small subset of free marketplace assets for tuning large language models and the subset has passed various checks for quality and safety filters.
|
||||
|
||||
Furthermore, all suggestions are generated **by** the AI model and do not transfer from one user to another. Since your code is not used for model training, it won't be suggested to other users of **Code Assist**, with the one exception of code being posted to free marketplace items.
|
||||
|
||||
## Multi-cursor
|
||||
|
||||
The Script Editor supports usage of multiple cursors to make edits simultaneously. You can add cursors based on your needs with a mouse click or keyboard shortcut. The initial cursor is called the **primary cursor** and additional cursors are called **secondary cursors**.
|
||||
|
||||
- Edits that you make at the primary cursor copy to the secondary cursors. Each edit counts as one action, so undo/redo of an edit applies to all cursors.
|
||||
- Widgets such as [autocomplete](#autocomplete-features) appear on the primary cursor but not the secondary cursors.
|
||||
- All of the standard [keyboard shortcuts](#keyboard-shortcuts) for script editing work with multi-cursor editing, including code indentation, toggling comments, and deleting lines.
|
||||
|
||||
The following table summarizes multi-cursor workflows and their shortcuts.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Command</th>
|
||||
<th>Windows</th>
|
||||
<th>Mac</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Add/remove cursor at mouse location**</td>
|
||||
<td><kbd>Alt</kbd> + click</td>
|
||||
<td><kbd>⌥</kbd> + click</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Remove most recently added cursor**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>U</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>U</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Add/modify cursor on mouse drag**</td>
|
||||
<td><kbd>Alt</kbd> + drag</td>
|
||||
<td><kbd>⌥</kbd> + drag</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Add cursor above/below**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Alt</kbd><kbd>↑</kbd> / <kbd>Ctrl</kbd><kbd>Alt</kbd><kbd>↓</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>⌥</kbd><kbd>↑</kbd> / <kbd>⌘</kbd><kbd>⌥</kbd><kbd>↓</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Add cursor to next matching selection**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>D</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>D</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Add cursor to every matching selection**</td>
|
||||
<td><kbd>Shift</kbd><kbd>Alt</kbd><kbd>L</kbd></td>
|
||||
<td><kbd>Shift</kbd><kbd>⌥</kbd><kbd>L</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Column/block select**</td>
|
||||
<td><kbd>Shift</kbd><kbd>Alt</kbd> + drag</td>
|
||||
<td><kbd>Shift</kbd><kbd>⌥</kbd> + drag</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Split selections into lines**</td>
|
||||
<td><kbd>Shift</kbd><kbd>Alt</kbd><kbd>I</kbd></td>
|
||||
<td><kbd>Shift</kbd><kbd>⌥</kbd><kbd>I</kbd></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<Alert severity="info">
|
||||
To remove all secondary cursors, exit multi-cursor editing, and return to the primary cursor, press <kbd>Esc</kbd>.
|
||||
</Alert>
|
||||
|
||||
### Add cursors
|
||||
|
||||
You can add cursors with a combination of keyboard shortcuts and mouse maneuvers. Cursors merge if they occupy the same space, such as if you add cursors with arrow keys or delete all the characters between cursors.
|
||||
|
||||
#### At mouse location
|
||||
|
||||
To add a cursor at your mouse pointer location:
|
||||
|
||||
1. Hold <kbd>Alt</kbd> on Windows or <kbd>⌥</kbd> on Mac.
|
||||
2. Click where you want to add the cursor.
|
||||
|
||||
<video controls width="512" src="../assets/studio/script-editor/AddWithClick.mp4"></video>
|
||||
|
||||
#### With mouse drag
|
||||
|
||||
You can drag the mouse to add a cursor to a selection, split a multi-line selection into lines, or select columns and blocks of code/whitespace.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Drag select">
|
||||
To add a cursor to a selection of code through dragging:
|
||||
|
||||
1. Hold <kbd>Alt</kbd> on Windows or <kbd>⌥</kbd> on Mac.
|
||||
2. Click and drag your mouse over the selection of code.
|
||||
|
||||
<video controls width="512" src="../assets/studio/script-editor/AddWithDrag.mp4"></video>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Split into lines">
|
||||
To split a multi-line selection into lines and add a cursor at the end of each line, press <kbd>Shift</kbd><kbd>Alt</kbd><kbd>I</kbd> on Windows or <kbd>Shift</kbd><kbd>⌥</kbd><kbd>I</kbd> on Mac.
|
||||
|
||||
<video controls width="405" src="../assets/studio/script-editor/SplitSelectionsIntoLines.mp4"></video>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Column/block select">
|
||||
To select columns and blocks of code or whitespace, drag the mouse while holding <kbd>Shift</kbd><kbd>Alt</kbd> on Windows or <kbd>Shift</kbd><kbd>⌥</kbd> on Mac. As you drag, a cursor will be added on each highlighted line.
|
||||
|
||||
<video controls width="405" src="../assets/studio/script-editor/ColumnBlockSelect.mp4"></video>
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Above and below primary cursor
|
||||
|
||||
To add a cursor directly above or below the primary cursor:
|
||||
|
||||
1. Press and hold <kbd>Ctrl</kbd><kbd>Alt</kbd> on Windows or <kbd>⌘</kbd><kbd>⌥</kbd> on Mac.
|
||||
2. Press the <kbd>↑</kbd> or <kbd>↓</kbd> arrows.
|
||||
|
||||
<video controls width="434" src="../assets/studio/script-editor/AddAboveBelow.mp4"></video>
|
||||
|
||||
#### To matching selections
|
||||
|
||||
You can add cursors to all matches of a selection or to the next/previous match, and optionally toggle whether matches are case-sensitive and/or match the whole word.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="All matching">
|
||||
To add a cursor to all matches of a selected portion:
|
||||
|
||||
1. Select the code that you want to search for matches of.
|
||||
2. Press <kbd>Shift</kbd><kbd>Alt</kbd><kbd>L</kbd> on Windows or <kbd>Shift</kbd><kbd>⌥</kbd><kbd>L</kbd> on Mac.
|
||||
|
||||
<video controls width="454" src="../assets/studio/script-editor/AddToAllMatches.mp4"></video>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Next/previous match">
|
||||
To add a cursor to the **next** matching selection:
|
||||
|
||||
1. Select the code that you want to search for matches of.
|
||||
2. Press <kbd>Ctrl</kbd><kbd>D</kbd> on Windows or <kbd>⌘</kbd><kbd>D</kbd> on Mac.
|
||||
3. Continue pressing <kbd>Ctrl</kbd><kbd>D</kbd> or <kbd>⌘</kbd><kbd>D</kbd> until you've selected all the next matches that you want.
|
||||
|
||||
<video controls width="454" src="../assets/studio/script-editor/AddToNextPrevMatch.mp4"></video>
|
||||
|
||||
There is no default shortcut for adding a cursor to the **previous** matching selection, but you can add your own:
|
||||
|
||||
1. Open **File** ⟩ **Advanced** ⟩ **Customize Shortcuts**.
|
||||
2. In the shortcuts window, locate **Select previous occurrence**.
|
||||
|
||||
<img src="../assets/studio/script-editor/Shortcut-Edit-Select-Prev.png" width="800" />
|
||||
|
||||
3. Double-click the action's **Shortcut** field and enter your own custom key combination, such as <kbd>Shift</kbd><kbd>Ctrl</kbd><kbd>D</kbd> to pair alongside "next" matching's default of <kbd>Ctrl</kbd><kbd>D</kbd>.
|
||||
4. Confirm your setting by clicking **OK** in the bottom-right corner of the window.
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Case or whole word match">
|
||||
For each of the matching-related workflows above, you can match **case** and/or **whole word** as follows:
|
||||
|
||||
1. Open the Find/Replace tool (<kbd>Ctrl</kbd><kbd>F</kbd> on Windows or <kbd>⌘</kbd><kbd>F</kbd> on Mac).
|
||||
2. Use the toggle buttons to choose if a matched selection should be case-sensitive and/or match the whole word only.
|
||||
|
||||
<img src="../assets/studio/script-editor/Find-Match-Case-Whole-Word.png" width="500" />
|
||||
|
||||
<video controls width="349" src="../assets/studio/script-editor/MatchCaseWholeWord1.mp4"></video>
|
||||
|
||||
<video controls width="485" src="../assets/studio/script-editor/MatchCaseWholeWord2.mp4"></video>
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Remove cursors
|
||||
|
||||
You can remove cursors with the following keyboard shortcuts and mouse maneuvers. Alternatively, you can exit multi-cursor editing by pressing <kbd>Esc</kbd>.
|
||||
|
||||
#### At mouse location
|
||||
|
||||
To remove a cursor:
|
||||
|
||||
1. Press and hold <kbd>Alt</kbd> on Windows or <kbd>⌥</kbd> on Mac.
|
||||
2. Click the cursor you want to remove.
|
||||
|
||||
<video controls width="485" src="../assets/studio/script-editor/RemoveWithClick.mp4"></video>
|
||||
|
||||
#### Most recently added
|
||||
|
||||
To remove the most recently added cursor, press <kbd>Ctrl</kbd><kbd>U</kbd> on Windows or <kbd>⌘</kbd><kbd>U</kbd> on Mac.
|
||||
|
||||
<video controls width="393" src="../assets/studio/script-editor/UndoRecentCursor.mp4"></video>
|
||||
|
||||
### Copy and paste cursors
|
||||
|
||||
Copying a selection of code includes the cursors within it. The behavior of the paste depends on the number of cursors at the source and the number of cursors at the destination:
|
||||
|
||||
- If the number of cursors are the same, then each copied cursor pastes to each corresponding destination cursor.
|
||||
- If the number of cursors are different, then each cursor at the destination receives the entire paste with each copied cursor as a new line.
|
||||
|
||||
<video controls width="679" src="../assets/studio/script-editor/CopyPaste.mp4"></video>
|
||||
|
||||
### On-type formatting
|
||||
|
||||
Pressing enter/return will auto-indent each cursor at the new line relative to
|
||||
the previous line. If the previous line starts with an incomplete block, the formatter will try to complete it.
|
||||
|
||||
<video controls width="459" src="../assets/studio/script-editor/OnTypeFormatting.mp4"></video>
|
||||
|
||||
## Editor settings
|
||||
|
||||
Many customization options are accessible via the **Script Editor** tab of [Studio Settings](../studio/setup.md#customization). Commonly modified options include:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Font**</td>
|
||||
<td>Font face and size for code in the editor.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Tab width**</td>
|
||||
<td>Number of spaces representing a <kbd>Tab</kbd> indent.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Indent using spaces**</td>
|
||||
<td>If enabled, spaces equal to **Tab Width** are inserted with <kbd>Tab</kbd> press.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Text wrapping**</td>
|
||||
<td>If enabled, longer lines of code wrap to the next line.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Script Editor color preset**</td>
|
||||
<td>Color preset for code elements, selection colors, and more. After choosing a preset, you can set specific colors for options like **Selection Color** and **Comment Color**.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Keyboard shortcuts
|
||||
|
||||
The Script Editor has the following keyboard shortcuts.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="File and display">
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Command</th>
|
||||
<th>Windows</th>
|
||||
<th>Mac</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Close script**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>W</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>W</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Reopen last closed script**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>T</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>Shift</kbd><kbd>T</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Quick open**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>P</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>P</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Show script in Explorer**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Alt</kbd><kbd>K</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>⌥</kbd><kbd>K</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Zoom in**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>=</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>=</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Zoom out**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>-</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>-</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Reset script zoom**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>0</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>0</kbd></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</TabItem>
|
||||
<TabItem label="Basic editing">
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Command</th>
|
||||
<th>Windows</th>
|
||||
<th>Mac</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Cut**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>X</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>X</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Copy**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>C</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>C</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Paste**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>V</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>V</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Undo**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Z</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>Z</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Redo**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Y</kbd></td>
|
||||
<td><kbd>Shift</kbd><kbd>⌘</kbd><kbd>Z</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Select all**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>A</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>A</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Find** / **Replace**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>F</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>F</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Find all** / **replace all**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>F</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>Shift</kbd><kbd>F</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Indent** / **unindent**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>\]</kbd> / <kbd>Ctrl</kbd><kbd>\[</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>\]</kbd> / <kbd>⌘</kbd><kbd>\[</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Toggle comment**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>/</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>/</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Expand all folds**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>E</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>E</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Collapse all folds**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>E</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>Shift</kbd><kbd>E</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Delete line**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>K</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>Shift</kbd><kbd>K</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Delete to start of line**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>Backspace</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>Delete</kbd></td>
|
||||
</tr><tr>
|
||||
<td>**Move line up/down**</td>
|
||||
<td><kbd>Alt</kbd><kbd>↑</kbd> / <kbd>Alt</kbd><kbd>↓</kbd></td>
|
||||
<td><kbd>⌥</kbd><kbd>↑</kbd> / <kbd>⌥</kbd><kbd>↓</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Go to declaration**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>F12</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>F12</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Open script function filter**</td>
|
||||
<td><kbd>Alt</kbd><kbd>F</kbd></td>
|
||||
<td><kbd>⌥</kbd><kbd>F</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Format selection**</td>
|
||||
<td><kbd>Alt</kbd><kbd>Shift</kbd><kbd>F</kbd></td>
|
||||
<td><kbd>⌥</kbd><kbd>Shift</kbd><kbd>F</kbd></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</TabItem>
|
||||
<TabItem label="Multi-Cursor">
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Command</th>
|
||||
<th>Windows</th>
|
||||
<th>Mac</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Add/remove cursor at mouse location**</td>
|
||||
<td><kbd>Alt</kbd> + click</td>
|
||||
<td><kbd>⌥</kbd> + click</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Remove most recently added cursor**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>U</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>U</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Add/modify cursor on mouse drag**</td>
|
||||
<td><kbd>Alt</kbd> + drag</td>
|
||||
<td><kbd>⌥</kbd> + drag</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Add cursor above/below**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>Alt</kbd><kbd>↑</kbd> / <kbd>Ctrl</kbd><kbd>Alt</kbd><kbd>↓</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>⌥</kbd><kbd>↑</kbd> / <kbd>⌘</kbd><kbd>⌥</kbd><kbd>↓</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Add cursor to next matching selection**</td>
|
||||
<td><kbd>Ctrl</kbd><kbd>D</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>D</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Add cursor to every matching selection**</td>
|
||||
<td><kbd>Shift</kbd><kbd>Alt</kbd><kbd>L</kbd></td>
|
||||
<td><kbd>Shift</kbd><kbd>⌥</kbd><kbd>L</kbd></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Column/block select**</td>
|
||||
<td><kbd>Shift</kbd><kbd>Alt</kbd> + drag</td>
|
||||
<td><kbd>Shift</kbd><kbd>⌥</kbd> + drag</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Split selections into lines**</td>
|
||||
<td><kbd>Shift</kbd><kbd>Alt</kbd><kbd>I</kbd></td>
|
||||
<td><kbd>Shift</kbd><kbd>⌥</kbd><kbd>I</kbd></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
49
.cursor/rules/roblox/en-us/studio/setup.md
Normal file
49
.cursor/rules/roblox/en-us/studio/setup.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
title: Roblox Studio setup
|
||||
description: Explains how to install Roblox Studio on your system.
|
||||
---
|
||||
|
||||
import StudioSystemReqs from '../includes/studio/system-reqs.md'
|
||||
|
||||
Create immersive 3D experiences on Roblox with **Roblox Studio**, a free application available on Windows and Mac.
|
||||
|
||||
## System requirements
|
||||
|
||||
<StudioSystemReqs components={props.components} />
|
||||
|
||||
## Installation
|
||||
|
||||
1. Click the following **Download Studio** button.
|
||||
|
||||
<UseStudioButton variant='blueLogoIconButton' />
|
||||
|
||||
1. In the pop-up dialog, click the **Download Studio** button.
|
||||
1. Find the Studio installer in your browser's download history and double-click the file.
|
||||
|
||||
- On Windows, the file is `RobloxStudio.exe`.
|
||||
- On Mac, the file is `RobloxStudio.dmg`.
|
||||
|
||||
1. After Studio finishes installing, a pop-up confirmation displays. Click the **Launch Studio** button.
|
||||
|
||||
1. Sign in to Studio with your Roblox account (if you don't have an account, create one at [roblox.com](https://www.roblox.com/)).
|
||||
|
||||
## Customization
|
||||
|
||||
You can customize Studio to suit your workflow across various levels:
|
||||
|
||||
- [Configure the toolbar](../studio/ui-overview.md#toolbar-and-mezzanine) with custom tabs, reorganize tools within custom tabs, hide infrequently used tabs, and more.
|
||||
- Customize the [window layout](../studio/ui-overview.md#layout-customization) to best suit your workflows.
|
||||
- View/edit Studio shortcuts and bind actions without defaults through **File** ⟩ **Customize Shortcuts**.
|
||||
- Access a wide array of **Studio Settings** (<kbd>Alt</kbd><kbd>S</kbd> on Windows; <kbd>⌥</kbd><kbd>S</kbd> on Mac). Locate known settings by typing keywords into the search field at the top of the window, for example `theme` to locate the setting for dark theme or light theme.
|
||||
|
||||
## Updates
|
||||
|
||||
In contrast to certain other engines, every experience runs on the latest version of the Roblox engine. You should keep Studio up‑to‑date to utilize the latest APIs and features.
|
||||
|
||||
If your current version of Studio is outdated, you'll see an **Update** button in the upper‑right corner. Clicking the button will prompt you to save/close the currently open place so that Studio can automatically update and restart.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Update-Available.png" width="800" alt="Update button in Studio highlighted." />
|
||||
|
||||
## Beta features
|
||||
|
||||
Many beta features are available through Studio's **File** ⟩ **Beta Features** menu. Once you've enabled beta features, click the **Save** button and you'll be prompted to restart Studio for the features to take effect.
|
||||
660
.cursor/rules/roblox/en-us/studio/terrain-editor.md
Normal file
660
.cursor/rules/roblox/en-us/studio/terrain-editor.md
Normal file
|
|
@ -0,0 +1,660 @@
|
|||
---
|
||||
title: Terrain Editor
|
||||
description: The Terrain Editor tools generate and sculpt realistic terrain environments such as mountains, bodies of water, grass-covered hills, or a flat desert.
|
||||
---
|
||||
|
||||
The **Terrain Editor**, accessible from Studio's **Home** tab or **Window** ⟩ **3D** menu, lets you generate and manipulate [environmental terrain](../parts/terrain.md) through its [Create](#create-tab) and [Edit](#edit-tab) toolsets.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Terrain-Editor.png" width="800" alt="Terrain Editor indicated in Studio's toolbar" />
|
||||
|
||||
<Alert severity="success">
|
||||
For detailed instructions on working with terrain, see the [environmental terrain](../parts/terrain.md) guide.
|
||||
</Alert>
|
||||
|
||||
## Create tab
|
||||
|
||||
The **Create** tab includes the [Import](#import), [Generate](#generate), and [Clear](#clear) tools.
|
||||
|
||||
### Import
|
||||
|
||||
The **Import** tool imports a [heightmap](../parts/terrain.md#heightmaps-and-colormaps) and optional [colormap](../parts/terrain.md#heightmaps-and-colormaps) and applies them to a selected region.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Create-Tab-Import.png" width="360" alt="Import tool indicated in Create tab of Terrain Editor" />
|
||||
|
||||
<GridContainer numColumns="3">
|
||||
<figure>
|
||||
<img src="../assets/modeling/terrain/Terrain-Heightmap.png" alt="Example heightmap image" />
|
||||
<figcaption>Heightmap</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="../assets/modeling/terrain/Terrain-Colormap.png" alt="Example colormap image" />
|
||||
<figcaption>Colormap</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="../assets/modeling/terrain/Terrain-Colormap-Result.jpg" alt="Terrain generated from the example heightmap and colormap" />
|
||||
<figcaption>Generated terrain</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
<video src="../assets/studio/terrain-editor/Import-Tool.mp4" controls width="90%" alt="Video of terrain generating automatically via the Import tool"></video>
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Selection settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2">Size, position, and snapping options as outlined for the [Select](#select) tool.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Heightmap settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Heightmap**</td>
|
||||
<td>Imports a heightmap from a local image file.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Colormap**</td>
|
||||
<td>Imports a colormap from a local image file to use alongside a heightmap.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Default Material**</td>
|
||||
<td>Specifies one consistent material to apply across all of the generated terrain. This is overridden by materials based on the colormap, if imported.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Generate
|
||||
|
||||
The **Generate** tool procedurally generates terrain within a selected region. This is useful if you want to create a large map and then fine-tune terrain details using the [Edit](#edit-tab) tab tools.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Create-Tab-Generate.png" width="360" alt="Generate tool indicated in Create tab of Terrain Editor" />
|
||||
|
||||
<video src="../assets/studio/terrain-editor/Generate-Tool.mp4" controls width="90%" alt="Video of terrain generating procedurally via the Generate tool"></video>
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Selection settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2">Size, position, and snapping options as outlined for the [Select](#select) tool.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Biome settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Biomes**</td>
|
||||
<td>Includes the selected biomes in the generated terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Blending**</td>
|
||||
<td>Adjusts how the biomes blend into one another, with higher values a bit smoother.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Caves**</td>
|
||||
<td>Includes caves in the generated terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Biome Size**</td>
|
||||
<td>Sets the size of the biomes within the overall terrain size.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Seed**</td>
|
||||
<td>A number that Studio generates to determine the shape of the terrain. When you change this number, Studio generates a new terrain with the same settings.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Clear
|
||||
|
||||
The **Clear** tool reveals a button that clears all terrain within the entire place.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Create-Tab-Clear.png" width="360" alt="Clear tool indicated in Create tab of Terrain Editor" />
|
||||
|
||||
## Edit tab
|
||||
|
||||
The **Edit** tab includes the [Select](#select), [Transform](#transform), [Fill](#fill), [Sea Level](#sea-level), [Draw](#draw), [Sculpt](#sculpt), [Smooth](#smooth), [Paint](#paint), and [Flatten](#flatten) tools.
|
||||
|
||||
### Select
|
||||
|
||||
The **Select** tool is a universal tool for selecting rectangular regions of terrain. With the tool enabled, select a region by clicking and dragging in the 3D viewport, reposition it with the **move** draggers, and edit its size with the **scale** handles. Alternatively, enter values into the tool's **X**/**Y**/**Z** inputs to set a specific position and size.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Edit-Tab-Select.png" width="360" alt="Select tool indicated in Edit tab of Terrain Editor" />
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Selection settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Size**</td>
|
||||
<td>Sets specific **X**/**Y**/**Z** values for the selection's size, in studs.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Position**</td>
|
||||
<td>Sets specific **X**/**Y**/**Z** values for the selection's position.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Snap to Voxels**</td>
|
||||
<td>Snaps the selection bounds to the nearest voxel.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<figure>
|
||||
<img src="../assets/studio/terrain-editor/Select-Region-Labeled.jpg" width="800" alt="Move draggers and scale handles on a selected region" />
|
||||
<figcaption>Move draggers and scale handles on a selected region</figcaption>
|
||||
</figure>
|
||||
|
||||
Studio also supports the following keyboard and mouse shortcuts, assuming the **Select** tool is active and nothing is selected in the [Explorer](../studio/explorer.md) hierarchy.
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Windows</th>
|
||||
<th>Mac</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><kbd>Ctrl</kbd><kbd>C</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>C</kbd></td>
|
||||
<td>Copy terrain within the selected region to the clipboard.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Ctrl</kbd><kbd>V</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>V</kbd></td>
|
||||
<td>Paste terrain that has been copied to the clipboard and swap to the [Transform](#transform) tool so that the new terrain can be transformed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Ctrl</kbd><kbd>X</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>X</kbd></td>
|
||||
<td>Cut terrain within the selected region to the clipboard.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Ctrl</kbd><kbd>D</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>D</kbd></td>
|
||||
<td>Duplicate terrain within the selected region and swap to the [Transform](#transform) tool so that the new terrain can be transformed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Delete</kbd></td>
|
||||
<td><kbd>Delete</kbd></td>
|
||||
<td>Delete terrain within the selected region.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Shift</kbd></td>
|
||||
<td><kbd>Shift</kbd></td>
|
||||
<td>When held down while dragging any **scale** handle, scales the region proportionally across all other axes.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Ctrl</kbd></td>
|
||||
<td><kbd>⌘</kbd></td>
|
||||
<td>When held down while dragging any **scale** handle, scales the region equally in both the positive and negative direction along that axis.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Transform
|
||||
|
||||
The **Transform** tool manipulates entire [selected](#select) regions to a new position, size, or orientation. With the tool enabled, transform a selected region with the **move** draggers, **rotate** rings, and **scale** handles. Alternatively, enter values into the tool's **X**/**Y**/**Z** inputs to set a specific position, size, and rotation.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Edit-Tab-Transform.png" width="360" alt="Transform tool indicated in Edit tab of Terrain Editor" />
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Transform settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Size**</td>
|
||||
<td>Sets specific **X**/**Y**/**Z** values for the selection's size in studs.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Position**</td>
|
||||
<td>Sets specific **X**/**Y**/**Z** values for the selection's position.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Rotation**</td>
|
||||
<td>Sets specific **X**/**Y**/**Z** values for the selection's rotation in degrees.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Merge Empty**</td>
|
||||
<td>When enabled, air voxels in the selection will overwrite existing voxels at the destination.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Live Edit**</td>
|
||||
<td>When enabled, terrain is constantly updated while being transformed. To view only a wireframe preview of the transformation, disable live edit mode and then, while transforming, press <kbd>Enter</kbd>/<kbd>Return</kbd> or click the **Apply** button to apply the changes.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Snap to Voxels**</td>
|
||||
<td>Snaps the selection bounds to the nearest voxel.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<figure>
|
||||
<img src="../assets/studio/terrain-editor/Transform-Region-Labeled.jpg" width="780" alt="Move draggers, rotate rings, and scale handles on a selected region" />
|
||||
<figcaption>Move draggers, rotate rings, and scale handles on a selected region</figcaption>
|
||||
</figure>
|
||||
|
||||
<Alert severity="warning">
|
||||
Before rotating a region with the visual **rotate** rings, check the rotation snapping setting in Studio's toolbar. Disable rotation snapping entirely for free-form rotation.
|
||||
</Alert>
|
||||
|
||||
<Alert severity="info">
|
||||
Similar to [selecting](#select) a region, holding <kbd>Shift</kbd> while dragging any **scale** handle scales the region proportionally across all other axes, and holding <kbd>Ctrl</kbd> or <kbd>⌘</kbd> while dragging scales the region equally in both the positive and negative direction along that axis.
|
||||
</Alert>
|
||||
|
||||
### Fill
|
||||
|
||||
The **Fill** tool fills an entire [selected](#select) region with a specific material, or replaces all material within the region with another material.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Edit-Tab-Fill.png" width="360" alt="Fill tool indicated in Edit tab of Terrain Editor" />
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Selection settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2">Size, position, and snapping options as outlined for the [Select](#select) tool.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Material settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Fill Mode**</td>
|
||||
<td>Toggles the tool between **Fill** and **Replace** mode.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Source Material**</td>
|
||||
<td>In **Fill** mode, the desired fill material. In **Replace** mode, the material to replace.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Target Material**</td>
|
||||
<td>In **Replace** mode, the material to replace the source material with.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<figure>
|
||||
<img src="../assets/studio/terrain-editor/Fill-Region.jpg" width="780" alt="Region filled with Salt material" />
|
||||
<figcaption>Selected region filled with Salt material</figcaption>
|
||||
</figure>
|
||||
|
||||
### Sea Level
|
||||
|
||||
The **Sea Level** tool lets you create a consistent water level or remove all water within a region.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Edit-Tab-Sea-Level.png" width="360" alt="Sea Level tool indicated in Edit tab of Terrain Editor" />
|
||||
|
||||
<video src="../assets/studio/terrain-editor/Sea-Level-Tool.mp4" controls width="90%" alt="Video of sea level being created and modified using the Sea Level tool"></video>
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Sea level settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Size**</td>
|
||||
<td>Sets specific **X**/**Y**/**Z** values for the selection's size in studs.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Position**</td>
|
||||
<td>Sets specific **X**/**Y**/**Z** values for the selection's position.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Snap to Voxels**</td>
|
||||
<td>Snaps the selection bounds to the nearest voxel.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Draw
|
||||
|
||||
The **Draw** tool **adds** or **subtracts** terrain using the brush. This tool functions in a dual mode where holding down <kbd>Ctrl</kbd> or <kbd>⌘</kbd> toggles on "subtract" mode instead of the default "add" mode. Additionally, holding down <kbd>Shift</kbd> temporarily activates the [Smooth](#smooth) tool.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Edit-Tab-Draw.png" width="360" alt="Draw tool indicated in Edit tab of Terrain Editor" />
|
||||
|
||||
<video src="../assets/studio/terrain-editor/Draw-Tool.mp4" controls width="90%" alt="Video of terrain being added and subtracted using the Draw tool"></video>
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Brush settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Brush Mode**</td>
|
||||
<td>Toggles the tool between **Add** and **Subtract** mode. Also toggled by holding down <kbd>Ctrl</kbd> or <kbd>⌘</kbd>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Brush Shape**</td>
|
||||
<td>Sets the brush shape to either a **sphere**, **box**, or **cylinder**.<br /><img src="../assets/studio/terrain-editor/Brush-Shape-Icons.png" width="124" alt="Brush shape icons in the Terrain Editor" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Brush Size**</td>
|
||||
<td>Sets the brush size from 1 to 64. If you choose a brush shape of **box** or **cylinder**, a **Height** slider/input also appears to adjust the brush height proportionally or independently of the base size.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Pivot Position**</td>
|
||||
<td>Sets the vertical pivot point of the brush to either the bottom, center, or top of where the brush connects with existing terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Snapping**</td>
|
||||
<td>Whether snapping is off or to the nearest voxel.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Plane Lock**</td>
|
||||
<td>Toggles whether to enable a visual plane which the brush locks to. In **Auto** mode, the plane tilts and rotates with the camera. In **Manual** mode, the **Edit Plane** option appears, letting you set a specific position/orientation through the visual draggers or **X**/**Y**/**Z** inputs.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Ignore Water**</td>
|
||||
<td>Ignores water when adding or subtracting terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Ignore Parts**</td>
|
||||
<td>Ignores [parts](../parts/index.md) in regards to brush placement while moving the mouse pointer across part surfaces.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Material settings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Auto Material**</td>
|
||||
<td>Uses the same terrain material in the brush's vicinity when adding new terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Source Material**</td>
|
||||
<td>Sets the [material](../parts/terrain.md#terrain-materials) for **Add** mode.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Sculpt
|
||||
|
||||
The **Sculpt** tool **adds** or **subtracts** terrain using the brush. Unlike the [Draw](#draw) tool, this tool includes a **strength** slider/input to allow for more gentle manipulation of terrain. This tool functions in a dual mode where holding down <kbd>Ctrl</kbd> or <kbd>⌘</kbd> toggles on "subtract" mode instead of the default "add" mode, and holding down <kbd>Shift</kbd> temporarily activates the [Smooth](#smooth) tool.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Edit-Tab-Sculpt.png" width="360" alt="Sculpt tool indicated in Edit tab of Terrain Editor" />
|
||||
|
||||
<video src="../assets/studio/terrain-editor/Sculpt-Tool.mp4" controls width="90%" alt="Video of terrain being added and subtracted using the Sculpt tool"></video>
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Brush Mode**</td>
|
||||
<td>Toggles the tool between **Add** and **Subtract** mode. Also toggled by holding down <kbd>Ctrl</kbd> or <kbd>⌘</kbd>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Brush Shape**</td>
|
||||
<td>Sets the brush shape to either a **sphere**, **box**, or **cylinder**.<br /><img src="../assets/studio/terrain-editor/Brush-Shape-Icons.png" width="124" alt="Brush shape icons in the Terrain Editor" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Brush Size**</td>
|
||||
<td>Sets the brush size from 1 to 64. If you choose a brush shape of **box** or **cylinder**, a **Height** slider/input also appears to adjust the brush height proportionally or independently of the base size.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Strength**</td>
|
||||
<td>Sets the brush strength from 0.1 to 1.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Plane Lock**</td>
|
||||
<td>Toggles whether to enable a visual plane which the brush locks to. In **Auto** mode, the plane tilts and rotates with the camera. In **Manual** mode, the **Edit Plane** option appears, letting you set a specific position/orientation through the visual draggers or **X**/**Y**/**Z** inputs.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Ignore Water**</td>
|
||||
<td>Ignores water when adding or subtracting terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Ignore Parts**</td>
|
||||
<td>Ignores [parts](../parts/index.md) in regards to brush placement while moving the mouse pointer across part surfaces.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Auto Material**</td>
|
||||
<td>Uses the same terrain material in the brush's vicinity when adding new terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Source Material**</td>
|
||||
<td>Sets the [material](../parts/terrain.md#terrain-materials) for **Add** mode.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Smooth
|
||||
|
||||
The **Smooth** tool smoothes out abrupt edges in terrain using the brush. This tool can be used in standalone mode, or you can toggle it on by holding <kbd>Shift</kbd> while using the [Draw](#draw) or [Sculpt](#sculpt) tools.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Edit-Tab-Smooth.png" width="360" alt="Smooth tool indicated in Edit tab of Terrain Editor" />
|
||||
|
||||
<video src="../assets/studio/terrain-editor/Smooth-Tool.mp4" controls width="90%" alt="Video of terrain being smoothed using the Smooth tool"></video>
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Brush Shape**</td>
|
||||
<td>Sets the brush shape to either a **sphere**, **box**, or **cylinder**.<br /><img src="../assets/studio/terrain-editor/Brush-Shape-Icons.png" width="124" alt="Brush shape icons in the Terrain Editor" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Brush Size**</td>
|
||||
<td>Sets the brush size from 1 to 64. If you choose a brush shape of **box** or **cylinder**, a **Height** slider/input also appears to adjust the brush height proportionally or independently of the base size.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Strength**</td>
|
||||
<td>Sets the brush strength from 0.1 to 1.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Pivot Position**</td>
|
||||
<td>Sets the vertical pivot point of the brush to either the bottom, center, or top of where the brush connects with existing terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Snapping**</td>
|
||||
<td>Whether snapping is off or to the nearest voxel.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Plane Lock**</td>
|
||||
<td>Toggles whether to enable a visual plane which the brush locks to. In **Auto** mode, the plane tilts and rotates with the camera. In **Manual** mode, the **Edit Plane** option appears, letting you set a specific position/orientation through the visual draggers or **X**/**Y**/**Z** inputs.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Ignore Water**</td>
|
||||
<td>Ignores water when smoothing terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Ignore Parts**</td>
|
||||
<td>Ignores [parts](../parts/index.md) in regards to brush placement while moving the mouse pointer across part surfaces.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Paint
|
||||
|
||||
The **Paint** tool, using the brush, **paints** a terrain [material](../parts/terrain.md#terrain-materials) over an existing material or **replaces** one material with another material.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Edit-Tab-Paint.png" width="360" alt="Paint tool indicated in Edit tab of Terrain Editor" />
|
||||
|
||||
<video src="../assets/studio/terrain-editor/Paint-Tool.mp4" controls width="90%" alt="Video of terrain being painted and replaced using the Paint tool"></video>
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Brush Shape**</td>
|
||||
<td>Sets the brush shape to either a **sphere**, **box**, or **cylinder**.<br /><img src="../assets/studio/terrain-editor/Brush-Shape-Icons.png" width="124" alt="Brush shape icons in the Terrain Editor" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Brush Size**</td>
|
||||
<td>Sets the brush size from 1 to 64. If you choose a brush shape of **box** or **cylinder**, a **Height** slider/input also appears to adjust the brush height proportionally or independently of the base size.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Pivot Position**</td>
|
||||
<td>Sets the vertical pivot point of the brush to either the bottom, center, or top of where the brush connects with existing terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Snapping**</td>
|
||||
<td>Whether snapping is off or to the nearest voxel.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Plane Lock**</td>
|
||||
<td>Toggles whether to enable a visual plane which the brush locks to. In **Auto** mode, the plane tilts and rotates with the camera. In **Manual** mode, the **Edit Plane** option appears, letting you set a specific position/orientation through the visual draggers or **X**/**Y**/**Z** inputs.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Ignore Water**</td>
|
||||
<td>Ignores water when flattening terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Ignore Parts**</td>
|
||||
<td>Ignores [parts](../parts/index.md) in regards to brush placement while moving the mouse pointer across part surfaces.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Material Mode**</td>
|
||||
<td>Toggles the tool between **Paint** and **Replace** mode. In **Paint** mode, choose the desired painting material from the tool's picker tiles. In **Replace** mode, choose both the **source** material to replace and the **target** material to replace it with.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Flatten
|
||||
|
||||
The **Flatten** tool flattens terrain to a consistent level across a visualized plane. By default, the tool lowers terrain above the plane **and** raises terrain below to the plane, but you can opt to selectively lower **or** raise through the tool's **Flatten Mode** option.
|
||||
|
||||
<img src="../assets/studio/terrain-editor/Edit-Tab-Flatten.png" width="360" alt="Flatten tool indicated in Edit tab of Terrain Editor" />
|
||||
|
||||
<video src="../assets/studio/terrain-editor/Flatten-Tool.mp4" controls width="90%" alt="Video of terrain being flattened to a plane using the Flatten tool"></video>
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Brush Shape**</td>
|
||||
<td>Sets the brush shape to either a **sphere**, **box**, or **cylinder**.<br /><img src="../assets/studio/terrain-editor/Brush-Shape-Icons.png" width="124" alt="Brush shape icons in the Terrain Editor" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Flatten Mode**</td>
|
||||
<td>**Erode to Flat**¹ flattens terrain above the plane. **Grow to Flat**² fills in terrain below the plane. **Flatten All**³ removes terrain above the plane and fills in terrain below the plane.<br /><img src="../assets/studio/terrain-editor/Flatten-Mode-Icons.png" width="124" alt="Flatten Mode icons in the Terrain Editor" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Brush Size**</td>
|
||||
<td>Sets the brush size from 1 to 64. If you choose a brush shape of **box** or **cylinder**, a **Height** slider/input also appears to adjust the brush height proportionally or independently of the base size.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Strength**</td>
|
||||
<td>Sets the brush strength from 0.1 to 1.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Pivot Position**</td>
|
||||
<td>Sets the vertical pivot point of the brush to either the bottom, center, or top of where the brush connects with existing terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Snapping**</td>
|
||||
<td>Whether snapping is off or to the nearest voxel.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Flatten Plane**</td>
|
||||
<td>If set to **Fixed**, flattens terrain to a fixed visual plane in **Y** world space.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Ignore Water**</td>
|
||||
<td>Ignores water when flattening terrain.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Ignore Parts**</td>
|
||||
<td>Ignores [parts](../parts/index.md) in regards to brush placement while moving the mouse pointer across part surfaces.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Studio shortcuts
|
||||
|
||||
For tools which use the **brush** ([Draw](#draw), [Sculpt](#sculpt), [Smooth](#smooth), [Flatten](#flatten), [Paint](#paint)), Studio supports the following keyboard and mouse shortcuts.
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Windows</th>
|
||||
<th>Mac</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><kbd>Ctrl</kbd></td>
|
||||
<td><kbd>⌘</kbd></td>
|
||||
<td>When held down while using the [Draw](#draw) and [Sculpt](#sculpt) tools, toggles on the alternate brush mode. For example, toggles on "subtract" mode instead of the default "add" mode.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Shift</kbd></td>
|
||||
<td><kbd>Shift</kbd></td>
|
||||
<td>When held down while using the [Draw](#draw) and [Sculpt](#sculpt) tools, temporarily activates the [Smooth](#smooth) tool.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>B</kbd></td>
|
||||
<td><kbd>B</kbd></td>
|
||||
<td>When held down while dragging the mouse or using the scroll wheel, adjusts the brush's **base size**.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Ctrl</kbd><kbd>B</kbd></td>
|
||||
<td><kbd>⌘</kbd><kbd>B</kbd></td>
|
||||
<td>When held down while dragging the mouse or using the scroll wheel, adjusts the brush's **height**. Only applies if the brush's shape is set to **box** or **cylinder**.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Shift</kbd><kbd>B</kbd></td>
|
||||
<td><kbd>Shift</kbd><kbd>B</kbd></td>
|
||||
<td>When held down while dragging the mouse or using the scroll wheel, adjusts the brush's **strength**. Only applies when using the [Sculpt](#sculpt), [Smooth](#smooth), or [Flatten](#flatten) tool.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><kbd>Alt</kbd></td>
|
||||
<td><kbd>⌥</kbd></td>
|
||||
<td>When held down on mouse click, shows the material picker.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
301
.cursor/rules/roblox/en-us/studio/testing-modes.md
Normal file
301
.cursor/rules/roblox/en-us/studio/testing-modes.md
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
---
|
||||
title: Studio testing modes
|
||||
description: Explore the built-in Studio testing modes for experiences.
|
||||
---
|
||||
|
||||
import DeviceEmulator from '../includes/studio/device-emulator.md'
|
||||
import ControllerEmulator from '../includes/studio/controller-emulator.md'
|
||||
import PlaytestModes from '../includes/studio/playtest-modes.md'
|
||||
|
||||
Because of the underlying [client-server model](../projects/client-server.md) of the Roblox Engine, it's important that you test your experience in various modes before [releasing it to the public](../production/publishing/publish-experiences-and-places.md#make-experience-public). All of the testing options are accessible in the left portion of the mezzanine.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Controls.png" width="800" alt="Testing controls indicated in Studio's mezzanine." />
|
||||
|
||||
## Playtesting
|
||||
|
||||
There are three common options for playtesting an experience. Choose the desired option from the dropdown menu and click the **Play** button to its right to begin the playtest.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Mode-Test.png" width="800" alt="Test option in the testing modes dropdown of Studio's mezzanine." />
|
||||
|
||||
<PlaytestModes components={props.components} />
|
||||
|
||||
Once a playtest is running, additional options become available in the mezzanine.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Options.png" width="800" alt="Additional options available during a playtest from Studio's mezzanine." />
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Action</th>
|
||||
<th>Shortcut</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Pause** / **Resume**</td>
|
||||
<td></td>
|
||||
<td>Lets you [pause/resume physics and animations](#pauseresume).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Stop**</td>
|
||||
<td><kbd>Shift</kbd><kbd>F5</kbd></td>
|
||||
<td>Stops simulation of the experience and resets all objects and instances to how they were before the playtest.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Client** / **Server**</td>
|
||||
<td></td>
|
||||
<td>During playtesting in a "solo" mode (**Test** or **Test Here**), toggles between **Client** mode and **Server** mode. See [toggle client/server](../studio/testing-modes.md#toggle-clientserver) for details.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Toggle client/server
|
||||
|
||||
When testing in either **Test** or **Test Here** mode, Studio runs two separate simulations — one [client](../projects/client-server.md#client) simulation and one [server](../projects/client-server.md#server) simulation — which can provide a more accurate impression of how the experience will execute in production.
|
||||
|
||||
While solo playtesting, you can toggle between **Client** and **Server** modes by clicking the **Client/Server** toggle button. When you toggle, the button changes to reflect the current simulation mode.
|
||||
|
||||
<Grid container spacing={5}>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Client.png" width="320" />
|
||||
<figcaption>Client</figcaption>
|
||||
</figure>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Server.png" width="320" />
|
||||
<figcaption>Server</figcaption>
|
||||
</figure>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
Depending on the simulation mode, control of your character and the camera changes as follows:
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Client Mode">
|
||||
<figure>
|
||||
<img src="../assets/studio/debugging/Client-Server-Toggle-3D-Client.jpg" width="800" height="450" />
|
||||
<figcaption>In **Client** mode, the 3D viewport is surrounded by a **blue** border and the simulation uses your character controls and camera setup. This testing mode is a close simulation of the experience running on the Roblox application, without multiple players.</figcaption>
|
||||
</figure>
|
||||
</TabItem>
|
||||
<TabItem label="Server Mode">
|
||||
<figure>
|
||||
<img src="../assets/studio/debugging/Client-Server-Toggle-3D-Server.jpg" width="800" height="450" />
|
||||
<figcaption>In **Server** mode, the 3D viewport is surrounded by a **green** border and your character is inserted but is not under your control. You can move about the place with a free‑floating camera, select objects, and inspect their properties.</figcaption>
|
||||
</figure>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Within the [Explorer](../studio/explorer.md) window hierarchy, certain objects only exist in their expected containers.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<img src="../assets/studio/debugging/Client-Server-Toggle-Explorer-Client.png" width="320" alt="Explorer window showing items that exist on client only" />
|
||||
<figcaption>In **Client** mode, the expected client-side objects are present in the hierarchy, including those copied over from `Class.StarterPack` to the player's `Class.Backpack` and from `Class.StarterPlayer` into the player's `Class.PlayerScripts`.</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="../assets/studio/debugging/Client-Server-Toggle-Explorer-Server.png" width="320" alt="Explorer window showing items that exist on server only" />
|
||||
<figcaption>In **Server** mode, the expected server-side objects are present in the hierarchy, including scripts in `Class.ServerScriptService` and objects you placed in `Class.ServerStorage`.</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
In the [Output](../studio/output.md) window, messages are labeled **blue** (client) or **green** (server), indicating their origin from either the client or server. For messages output from `Class.ModuleScript|ModuleScripts`, the label color is determined by whether the module was called from a client-side `Class.LocalScript` or from a server-side `Class.Script`.
|
||||
|
||||
<img src="../assets/studio/general/Output-Window-Client-Server-Labels.png" width="800" alt="Output window showing green label for server output and blue label for client output" />
|
||||
|
||||
### Pause/resume
|
||||
|
||||
While solo playtesting, the **Pause/Resume** button is useful for debugging ephemeral scenes and mechanisms, without disabling rendering.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Pause.png" width="800" alt="Pause/Resume button indicated in Studio's mezzanine." />
|
||||
|
||||
By default, pausing and resuming acts upon both the client **and** server. If you wish to pause or resume only the client **or** server:
|
||||
|
||||
1. Set the [client/server toggle](#toggle-clientserver) based on which simulation you want to pause/resume.
|
||||
2. Click the small arrow on the **Pause/Resume** button and select the alternate option of **Pause/Resume Client** or **Pause/Resume Server**. Clicking the button will then pause or resume only that side of the simulation.
|
||||
|
||||
When the simulation is paused, you can **step forward** 1/60th of a second (60 Hz) by clicking the **Step Forward** button. Like the **Pause/Resume** button to its left, clicking the small arrow lets you select stepping for only the client **or** server based on the [client/server toggle](#toggle-clientserver).
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Step-Forward.png" width="800" alt="Step Forward button indicated in Studio's mezzanine." />
|
||||
|
||||
Note the following technical details in relation to pause/resume:
|
||||
|
||||
- Although `Class.Animation|Animations` are not based on physics, these toolbar buttons also pause/resume animations.
|
||||
- Pausing or resuming has no effect on running scripts.
|
||||
- Only the `Class.RunService` callbacks `Class.RunService.PreAnimation|PreAnimation`, `Class.RunService.PreSimulation|PreSimulation`, `Class.RunService.PostSimulation|PostSimulation`, and `Class.RunService.Stepped|Stepped` pause or resume through these toolbar buttons. Other callbacks (`Class.RunService.PreRender|PreRender`, `Class.RunService.Heartbeat|Heartbeat`, and `Class.RunService.RenderStepped|RenderStepped`) continue to fire, maintaining normal functionality of camera scripts, rendered visualizations, and plugins.
|
||||
|
||||
## Multi-client simulation
|
||||
|
||||
The **Server & Clients** option from the dropdown menu lets you launch multiple sessions of Studio, one acting as the server and each other acting as a client. This testing mode is a valuable tool for comparing how a client "sees" other clients within the experience.
|
||||
|
||||
1. With the **Server & Clients** option selected in the dropdown menu, choose the number of client sessions to test. Usually 1–2 clients is sufficient, although you can simulate up to eight.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Mode-Server-Clients.png" width="800" alt="Server & Clients option in the testing modes dropdown of Studio's mezzanine." />
|
||||
|
||||
1. Press the **Play** button or <kbd>F7</kbd> to begin the client-server simulation.
|
||||
1. When you're finished testing, press the **End Session** button from any of the simulation sessions to close all simulated clients and the simulated server.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-End-Session.png" width="800" alt="End Session indicated in Studio's mezzanine" />
|
||||
|
||||
## Party simulation
|
||||
|
||||
The **Party Simulator** allows you to test and debug experiences that use party-related APIs directly within Studio, without needing to publish and coordinate multiple devices. This tool lets you configure and emulate parties for test players in your [Server & Clients](#multi-client-simulation) play tests.
|
||||
|
||||
When play testing, Party Simulator automatically assigns all test players to the configured simulated parties.
|
||||
|
||||
<img src="../assets/studio/general/Party-Simulator.png" width="480" alt="Party Emulator displaying simulated parties and various assignment options" />
|
||||
|
||||
If Party Simulator is enabled:
|
||||
|
||||
- Each `Class.Player.PartyId` property reflects the Party Simulator assignments.
|
||||
- `Class.SocialService:GetPartyAsync()` returns a simulated table of party data.
|
||||
- `Class.SocialService:GetPlayersByPartyId()` returns a list of `Class.Player` instances assigned to the provided `Class.Player.PartyId`.
|
||||
|
||||
You can adjust the number of local test players at any time using Studio's [Server & Clients](#multi-client-simulation) setting. When the test player count changes, the emulator automatically updates to include or remove players in the configuration.
|
||||
|
||||
## Collaborative testing
|
||||
|
||||
If you're working on an experience with others in [collaboration](../projects/collaboration.md) mode, you can test with other collaborators as follows:
|
||||
|
||||
1. Select **Team Test** in the dropdown menu and press the **Play** button to open a new Studio session with your character inserted.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Mode-Team-Test.png" width="800" alt="Team Test option in the testing modes dropdown of Studio's mezzanine." />
|
||||
|
||||
1. Other collaborators can then join by pressing the **Play** button from the mezzanine in their Studio session.
|
||||
|
||||
<Alert severity="info">
|
||||
Only one team test session can run at any given time. To close a session and kick out all testers, click the **End Session** button.
|
||||
</Alert>
|
||||
|
||||
## Device emulation
|
||||
|
||||
<DeviceEmulator components={props.components} />
|
||||
|
||||
## Controller emulation
|
||||
|
||||
<ControllerEmulator components={props.components} />
|
||||
|
||||
## VR headsets
|
||||
|
||||
If you'd like to support virtual reality (VR) headsets for your experience, make sure to test or [emulate](#vr-emulation) VR in Studio.
|
||||
|
||||
### VR emulation
|
||||
|
||||
**VR emulation** lets you test VR experiences in Studio without a physical headset. Just like emulating any other device, use the [device selector](#device-emulation) menu to choose either **Meta Quest 2** or **Meta Quest 3**. The [controller emulator](#controller-emulation) automatically selects the appropriate controller for the headset.
|
||||
|
||||
<Grid container spacing={1}>
|
||||
<Grid item XSmall={12} Medium={6} Large={6} XLarge={6}><img src="../assets/studio/general/Controller-Emulator-VR.png" width="540" alt="The Controller Emulator with a Quest 3 controller." /></Grid>
|
||||
<Grid item XSmall={12} Medium={6} Large={6} XLarge={6}><img src="../assets/studio/general/Emulator-Viewport-VR.jpg" width="716" alt="Emulator with a Quest 3 emulation." /></Grid>
|
||||
</Grid>
|
||||
|
||||
The combination of a headset and multiple controllers, each with motion tracking, make VR emulation more complex:
|
||||
|
||||
- For motion tracking emulation, press <kbd>Alt</kbd><kbd>1</kbd> (<kbd>⌥</kbd><kbd>1</kbd>) to lock the mouse to and unlock the mouse from the viewport.
|
||||
|
||||
- Use <kbd>Shift</kbd><kbd>←</kbd> or <kbd>Shift</kbd><kbd>→</kbd> to switch between common combinations of the headset, left controller, and right controller. For example, you might use the **Headset** option to look around as you walk forward with the left controller button, but then switch to the **Right Controller** when you need to use motion controls to aim at a target.
|
||||
|
||||
### Headset configuration
|
||||
|
||||
Studio supports testing for all VR headsets that are compatible with [OpenXR](https://www.khronos.org/openxr/), the open‑source industry standard providing access to VR.
|
||||
|
||||
<Alert severity="info">
|
||||
Currently, testing in VR is only supported on Windows.
|
||||
</Alert>
|
||||
|
||||
To enable Studio testing in VR, you must connect your headset to your PC and configure the OpenXR runtime **before** launching Studio. If you've already launched Studio, quit and complete the configuration steps first.
|
||||
|
||||
If you only have one VR headset, installing the corresponding VR app automatically configures the runtime for you. If you have multiple headsets, you must set up the runtime manually and make sure to **only** configure the one that you want to use for testing.
|
||||
|
||||
The following steps are for the two most common VR apps:
|
||||
|
||||
- SteamVR for headsets such as the HTC Vive and Valve Index.
|
||||
- Oculus for headsets such as the Meta Quest and Oculus Rift.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Steam VR">
|
||||
|
||||
1. Install and open the SteamVR app on your computer.
|
||||
2. Under **SteamVR Settings**, select the **Developer** tab. Then select **Show Advanced Settings**.
|
||||
3. Set SteamVR as OpenXR runtime.
|
||||
4. Turn the controllers on by pressing the **System** button until you hear a beeping sound.
|
||||
- To turn the controller off, press and hold the **System** button until you hear the same beeping sound.
|
||||
|
||||
If you follow the steps correctly, the status icons on the SteamVR app and the status lights on the hardware should all be green, indicating that the configuration is completed.
|
||||
|
||||
<Alert severity="info">
|
||||
When you quit the SteamVR app, the controllers automatically turn off. The controllers also automatically turn off after being idle for a period of time.
|
||||
</Alert>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Oculus VR">
|
||||
|
||||
1. Install and open the Oculus app on your computer.
|
||||
2. Confirm that your device is connected and the status is ready.
|
||||
3. Under **Settings / General** in the Oculus app, select **OpenXR Runtime**.
|
||||
4. <Chip label="OPTIONAL" size="small" variant="outlined" /> Bring up the **Devices** tab and find your headset to confirm the configuration by checking if the status is green without errors.
|
||||
|
||||
<Alert severity="info">
|
||||
When using Oculus VR, ensure the following:
|
||||
- At minimum, Oculus drivers require an NVIDIA GeForce GTX 1060 graphics card or equivalent.
|
||||
- If you are using a Quest 2 with a link cable, you must enable the link inside the headset.
|
||||
</Alert>
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Roblox Quest app
|
||||
|
||||
You can test your experience in the Roblox app on Quest without linking your headset to your computer. Use the following steps to access your experience on your headset in this mode:
|
||||
|
||||
1. In Studio, publish the experience and set the experience to private.
|
||||
2. Using your [Creator Dashboard](https://create.roblox.com/dashboard/creations) or the link in Studio, open the experience page in your web browser.
|
||||
3. On the experience page, add the experience to your favorites by clicking the **Favorite** icon.
|
||||
4. Using your headset, open the standalone Roblox app.
|
||||
5. Scroll down to the **Favorites** section in the home page and run your experience.
|
||||
|
||||
### Studio VR mode
|
||||
|
||||
After [configuring your headset](#headset-configuration), you can turn on the Studio VR testing mode through the following steps:
|
||||
|
||||
1. In the **File** menu, select **Studio Settings**.
|
||||
2. Select **Rendering**.
|
||||
3. Under **General** settings, turn on **Enable VR Mode**.
|
||||
|
||||
You can now test your experience using your VR headset using any of the available [playtest options](#playtesting). During a VR testing session, if your headset cable disconnects or you close the Roblox Studio Beta app on the headset, you'll need to restart Studio to re-run testing.
|
||||
|
||||
## Player emulation
|
||||
|
||||
For detailed emulation of experience [localization](../production/localization/index.md) and content policies, you can test through the **Player Emulator**, accessible from Studio's **Test** menu.
|
||||
|
||||
With the emulator window open, toggle on **Enable Test Profile**. Emulation will remain as toggled (enabled or disabled) even if you close the window.
|
||||
|
||||
Lower down in the window, commonly used options include:
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Locale**</td>
|
||||
<td>Lets you emulate a [localized](../production/localization/index.md) language while playtesting.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Pseudolocalize**</td>
|
||||
<td>Swaps out characters with similar but slightly different characters so that it's easy to identify which strings are going through the [translation](../production/localization/index.md) system. Enabling this helps you identify **unlocalized** text without having to change the emulation language. For example:<ul><li><Typography variant="body1">`Bloxy Cola` ⟩ `ßℓôж¥ Çôℓá`</Typography></li><li><Typography variant="body1">`Dominus Empyreus` ⟩ `Ðô₥ïñúƨ É₥ƥ¥řèúƨ`</Typography></li></ul></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Elongate**</td>
|
||||
<td>Elongates text strings by a factor defined via the slider. For example:<ul><li><Typography variant="body1">`Bloxy Cola` ⟩ `Bloooxyy Coolaa` (50% longer)</Typography></li><li><Typography variant="body1">`Dominus Empyreus` ⟩ `Doomiinuus Eempyyreus` (30% longer)</Typography></li></ul>Using elongation helps you identify places where your user interfaces might not be able to handle text that's longer than the default translated text. Note that Spanish is on average 30% longer than English and the equivalent for German is even longer. Also note that this only affects text that goes through the [translation](../production/localization/index.md) system.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Region**</td>
|
||||
<td>Lets you emulate a player's country/region while playtesting; this selection may impact other toggles and checkboxes in the window as outlined in `Class.PolicyService:GetPolicyInfoForPlayerAsync()|GetPolicyInfoForPlayerAsync()`.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
210
.cursor/rules/roblox/en-us/studio/texture-generator.md
Normal file
210
.cursor/rules/roblox/en-us/studio/texture-generator.md
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
---
|
||||
title: Texture Generator
|
||||
description: The Texture Generator tool quickly creates custom textures for meshes through text prompts.
|
||||
---
|
||||
|
||||
import BetaAlert from '../includes/beta-features/beta-alert.md'
|
||||
|
||||
<BetaAlert betaName="Texture Generator" leadIn="This tool is currently in beta. Enable it through " leadOut="." components={props.components} />
|
||||
|
||||
The **Texture Generator** tool is designed to quickly create custom textures for your meshes through text prompts. You can select a mesh or `Class.Model` made up of several meshes¹, type in any prompt to preview results within a few seconds, then generate full textures.
|
||||
|
||||
<GridContainer numColumns="3">
|
||||
<figure>
|
||||
<img src="../assets/studio/texture-generator/Generation-Rusted-Metal-Charred.jpg" />
|
||||
<figcaption>"rusted metal castle"</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="../assets/studio/texture-generator/Generation-Mossy-Stone.jpg" />
|
||||
<figcaption>"mossy stone fortress"</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="../assets/studio/texture-generator/Generation-Snow-Covered-Ice.jpg" />
|
||||
<figcaption>"ice covered sculpture"</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
<Alert severity="info">
|
||||
**Texture Generator** is best suited for custom 3D assets where the desired texture is contextual to the asset itself. To generate repeating or tiled images for texturing surfaces like a wood floor or cobblestone pathway, [Material Generator](../studio/material-generator.md) may produce better results.
|
||||
</Alert>
|
||||
|
||||
<figcaption><sup>1</sup> When generating a texture for a `Class.Model` group of `Class.MeshPart|MeshParts`, the meshes should be arranged in a sensible way such that a unified body is formed. Avoid generating a texture for an arbitrary group of meshes scattered about the model's bounds, or for more than one identical mesh in the same operation.</figcaption>
|
||||
|
||||
## Generate textures
|
||||
|
||||
To begin generating textures, open the **Texture Generator** from Studio's **Window** ⟩ **3D** menu.
|
||||
|
||||
With the tool's window open:
|
||||
|
||||
1. Select a `Class.MeshPart` or a `Class.Model` comprised of `Class.MeshPart|MeshParts` in your scene.
|
||||
2. In the tool's preview pane, click/drag or enter **X**/**Y**/**Z** values to set the **generation angle** which highlights the significant features or surfaces for texturing. See [best practices](#best-practices) for tips on choosing a generation angle.
|
||||
|
||||
<Grid container spacing={3}>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/texture-generator/Generation-Angle-Good.png" width="360" alt="Good generation angle focusing on primary faces of a tower mesh" />
|
||||
<figcaption>
|
||||
<Alert severity="success" style={{maxWidth:"360px"}}>Focus on the primary faces of a tower mesh, visible to players</Alert>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/studio/texture-generator/Generation-Angle-Bad.png" width="360" alt="Bad generation angle focusing on bottom of tower mesh" />
|
||||
<figcaption>
|
||||
<Alert severity="warning" style={{maxWidth:"360px"}}>Bottom of tower mesh will not likely be visible to players</Alert>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
3. <Chip label="OPTIONAL" size="small" variant="outlined" /> Below the preview pane and prompt input text box, expand the **Art Style** section to upload an image or use an existing [image asset](../projects/assets/index.md) to influence the overall style, color palette, and mood of your generated texture.
|
||||
|
||||
<img src="../assets/studio/texture-generator/Art-Style.png" width="360" alt="Art Style options in the Texture Generator window" />
|
||||
|
||||
1. Expand the **Art Style** section of the tool's window.
|
||||
2. Specify an image asset that you've already [imported](../projects/assets/manager.md#importing-assets) to Roblox, or upload an image using the built‑in asset picker.
|
||||
3. Adjust the **Strength** value. A lower value blends the image more subtly while a higher value makes it the dominant style.
|
||||
|
||||
4. In the prompt text box input below the preview pane, enter a prompt describing your desired texture, for instance:
|
||||
|
||||
- `rusted metal castle`
|
||||
- `mossy stone fortress`
|
||||
- `snow covered ice sculpture`
|
||||
|
||||
Including `+`, `-`, or a number after keywords increases, decreases, or specifies the emphasis of that keyword, respectively. For example:
|
||||
|
||||
- `futuristic pirate++ backpack` puts stronger emphasis on `pirate`
|
||||
- `futuristic-- backpack` puts less emphasis on `futuristic` if the original result was too futuristic
|
||||
- `(robotic)1.5 pirate backpack` puts a precise emphasis on `robotic`
|
||||
|
||||
<Alert severity="info">
|
||||
Using more descriptors in your prompt and iterating can help you find a texture that suits your needs. For more information, see [best practices](#best-practices).
|
||||
</Alert>
|
||||
|
||||
5. Click **Preview** to create a texture preview. When the preview is ready:
|
||||
|
||||
- Use the "rotate" buttons to rotate the view 90° around the mesh.
|
||||
- Use the **Reroll** button to generate a new texture using the same parameters.
|
||||
- Click the "back" button to return to the prompt input text box.
|
||||
|
||||
<img src="../assets/studio/texture-generator/Generation-Post-Preview.png" width="360" alt="Texture preview showing in tool window" />
|
||||
|
||||
<Alert severity="info">
|
||||
In the preview stage, the texture may not appear visually consistent from all four views. However, the model will create a texture that's more consistent during the texture generation process.
|
||||
</Alert>
|
||||
|
||||
6. When you're satisfied with the texture, click **Save & Apply** to create a full texture for your mesh. When complete, the new texture will be applied to the mesh through a `Class.SurfaceAppearance` instance.
|
||||
|
||||
<img src="../assets/studio/texture-generator/Texture-Applied.jpg" width="720" alt="Texture applied to mesh in 3D world" />
|
||||
|
||||
Generated textures appear in the **Saved Textures** section of the tool's window. For each texture, you can click the **⋯** to access various options.
|
||||
|
||||
<img src="../assets/studio/texture-generator/Saved-Textures-List.png" width="360" alt="Saved Textures list in tool window" />
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Insert Mesh with Texture**</td>
|
||||
<td>Inserts a copy of the textured mesh/model into the workspace.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Show in Inventory**</td>
|
||||
<td>Opens your **Images** inventory on the [Creator Dashboard](https://create.roblox.com/dashboard/creations?activeTab=Image) where you can inspect the texture image.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Export**</td>
|
||||
<td>Exports the mesh to your local system as a `.obj` file.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Remove**</td>
|
||||
<td>Removes the texture from the **Saved Textures** list.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Advanced options
|
||||
|
||||
Expanding the **Advanced Options** section in the tool's window allows you to configure the following aspects.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Seed Control">
|
||||
You can choose to either randomize the seed or set a specific seed for texture generation. Setting a specific seed before generating a texture ensures you get consistent results each time you use a specific prompt.
|
||||
</TabItem>
|
||||
<TabItem label="Smart UV Unwrap">
|
||||
In 3D modeling, a **UV map** is a 2D representation of the surface of a 3D model, allowing 2D textures to be accurately applied to the 3D model. UV coordinates **U** and **V** refer to the horizontal and vertical axes of this 2D space, similar to the **X** and **Y** axes in a 2D graph.
|
||||
|
||||
For the texture generator tool to create well-formed textures, your mesh's underlying UV maps need to fit a few guidelines. First, all UV coordinates must be **within the unit square**, as UV maps outside of the unit square will wrap around to the other side of the UV map and create artifacts or seams in the final texture. Second, all UVs must be **non‑overlapping**, as overlapping UVs will result in inconsistent textures and color placements.
|
||||
|
||||
Selecting the **Smart UV Unwrap** option will take a mesh with no UVs (or incompatible UVs) and apply the necessary UV coordinates for texturing. If your UVs are compatible, they won't be affected and you can use your mesh as‑is.
|
||||
</TabItem>
|
||||
<TabItem label="Specify Front View">
|
||||
When this setting is enabled, the **generation angle** selected during the preview stage is specified as the "front" of your mesh. This allows the tool to better texture meshes with a clear front and back by identifying each side, resulting in more consistent and coherent textures. This is particularly helpful for objects with a clear front and back, like avatars, animals, and clothing.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item XSmall={6} XLarge={6}>
|
||||
<img src="../assets/studio/texture-generator/Specify-Front-View-Bad-Front.jpg" alt="Front view of character's lab coat with Specify Front View disabled" />
|
||||
</Grid>
|
||||
<Grid item XSmall={6} XLarge={6}>
|
||||
<img src="../assets/studio/texture-generator/Specify-Front-View-Bad-Back.jpg" alt="Back view of character's lab coat with Specify Front View disabled" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<figcaption>
|
||||
<Alert severity="error">
|
||||
"Lab Coat with Badge" prompt with **Specify Front View** disabled, yielding lab coat "front" on both front and back
|
||||
</Alert>
|
||||
</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item XSmall={6} XLarge={6}>
|
||||
<img src="../assets/studio/texture-generator/Specify-Front-View-Good-Front.jpg" alt="Front view of character's lab coat with Specify Front View enabled" />
|
||||
</Grid>
|
||||
<Grid item XSmall={6} XLarge={6}>
|
||||
<img src="../assets/studio/texture-generator/Specify-Front-View-Good-Back.jpg" alt="Back view of character's lab coat with Specify Front View enabled" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<figcaption>
|
||||
<Alert severity="success">
|
||||
Same prompt with **Specify Front View** enabled, yielding correct "front" and "back" of lab coat
|
||||
</Alert>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Best practices
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Prompting tips">
|
||||
The following prompting tips enable the tool to provide better and more consistent results.
|
||||
|
||||
- Provide as much detail as possible in your prompt. Short, vague prompts will lead to inconsistent or unexpected results.
|
||||
- Include texture attributes like material types, colors, patterns, wear and tear, etc. The more constraints you give the tool, the better it can generate what you have in mind.
|
||||
- Use descriptive phrases instead of single words for key items, for example "worn leather" instead of just "leather."
|
||||
- Add styling cues like "cinematic," "photorealistic," "cartoon," or "low poly" to influence the overall look.
|
||||
</TabItem>
|
||||
<TabItem label="Generation angle">
|
||||
The generation angle sets the most important view of your mesh which will be prioritized during generation. Changing this angle when [generating textures](#generate-textures) can often help eliminate inconsistencies in textures.
|
||||
|
||||
- Setting the generation angle to highlight the meaningful faces of your mesh will result in better generations.
|
||||
- For flat objects like plates, swords, and fences, make sure the generation angle displays a view with a high surface area.
|
||||
- For humanoid and animal meshes, experiment with different generation angles, such as a head-on view of the face and a side view profile, to find the most consistent and coherent texture.
|
||||
</TabItem>
|
||||
<TabItem label="Iterative refinement">
|
||||
Generating the most suitable textures is an iterative process. It helps to preview often and tweak prompts incrementally to reach your vision.
|
||||
|
||||
- If a texture doesn't meet your expectations, identify what to change instead of starting over. For example, tweak the color or pattern description.
|
||||
- Change the prompt word order. Words at the beginning of the prompt can have more weight when generating.
|
||||
- Generate several previews to compare different prompts, or try the same prompts with different [seeds](#advanced-options) to get a preview that fits your vision.
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
451
.cursor/rules/roblox/en-us/studio/ui-overview.md
Normal file
451
.cursor/rules/roblox/en-us/studio/ui-overview.md
Normal file
|
|
@ -0,0 +1,451 @@
|
|||
---
|
||||
title: Studio interface
|
||||
description: User interface overview for Roblox Studio, the essential building tool for Roblox experiences.
|
||||
---
|
||||
|
||||
import BetaAlert from '../includes/beta-features/beta-alert.md'
|
||||
import StudioCameraControls from '../includes/studio/camera-controls.md'
|
||||
|
||||
## Toolbar and mezzanine
|
||||
|
||||
The **toolbar** and **mezzanine** reside at the top of Studio.
|
||||
|
||||
<figure>
|
||||
<img src="../assets/studio/general/Toolbar-Mezzanine.png" width="960" alt="Mezzanine and toolbar indicated in Studio." />
|
||||
</figure>
|
||||
|
||||
<figure>
|
||||
The left side of the mezzanine contains easily-accessible [testing controls](../studio/testing-modes.md#playtest-options).
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Testing-Controls.png" width="800" alt="Testing controls indicated in Studio's mezzanine." />
|
||||
</figure>
|
||||
|
||||
<figure>
|
||||
The right side of the mezzanine contains buttons/menus for [collaboration](../projects/collaboration.md), sharing, [Assistant](../assistant/guide.md), creator notifications, and account options.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Right.png" width="800" alt="Other options indicated in Studio's mezzanine." />
|
||||
</figure>
|
||||
|
||||
<figure>
|
||||
In the center of the mezzanine are the default tool tabs of **Home**, **Model**, **Avatar**, **UI**, **Script**, and **Plugins**. You can also add [custom tabs](#custom-tabs) for your specific needs.
|
||||
|
||||
<img src="../assets/studio/general/Mezzanine-Default-Tabs.png" width="800" alt="Default tabs indicated in Studio's mezzanine." />
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Home">
|
||||
The **Home** tab contains the core [transform](../parts/index.md#transform-parts) tools, [part inserter](../parts/index.md#insert-parts), the [color](../parts/index.md#color) and [material](../parts/index.md#material) widgets, the [group](../parts/index.md#group) and [lock](../parts/index.md#lock) tools, and [anchor](../parts/index.md#anchor) toggle. Also contains the [Terrain Editor](./terrain-editor.md).
|
||||
</TabItem>
|
||||
<TabItem label="Model">
|
||||
The **Model** tab contains the core [transform](../parts/index.md#transform-parts) tools, the [pivot](../studio/pivot-tools.md) and [align](../studio/align-tool.md) tools, insertion widgets for [effects](../effects/index.md) and [constraints](../physics/index.md#constraints), and [solid‑modeling](../parts/solid-modeling.md) tools.
|
||||
</TabItem>
|
||||
<TabItem label="Avatar">
|
||||
The **Avatar** tab contains the core [transform](../parts/index.md#transform-parts) tools, as well as specialized tools for building default rigs, configuring [avatars](../avatar-setup/index.md), working with [animations](../animation/index.md), and [creating/fitting accessories](../art/accessories/accessory-fitting-tool.md).
|
||||
</TabItem>
|
||||
<TabItem label="UI">
|
||||
The **UI** tab contains insertion widgets for [UI objects](../ui/index.md#ui-objects) and lets you access the [Style Editor](../ui/styling/editor.md), a comprehensive tool that allows you to create, manage, and apply UI styles.
|
||||
</TabItem>
|
||||
<TabItem label="Script">
|
||||
The **Script** tab contains tools for writing and testing scripts, including [debugging](../studio/debugging.md) tools.
|
||||
</TabItem>
|
||||
<TabItem label="Plugins">
|
||||
The **Plugins** tab contains [plugins](./plugins.md) created by the community or plugins you've created yourself to use across your experiences.
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
</figure>
|
||||
|
||||
### Appearance
|
||||
|
||||
You can customize the appearance of the toolbar by right-clicking in an empty area within the mezzanine/toolbar and selecting from the following options:
|
||||
|
||||
- **Manage tabs** — Reveals a popup window with the following options:
|
||||
|
||||
<figure>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item Medium={12} Large={5} XLarge={5}>
|
||||
<img src="../assets/studio/general/Manage-Tabs-Popup.png" width="300" alt="The Manage Tabs popup in Studio." />
|
||||
</Grid>
|
||||
<Grid item Medium={12} Large={7} XLarge={7}>
|
||||
<ol style={{listStyleType: 'upper-alpha'}}>
|
||||
<li>Show or hide the tab.</li>
|
||||
<li>With a tab selected, reorder it relative to the other tabs.</li>
|
||||
<li>Delete a selected [custom tab](#custom-tabs).</li>
|
||||
<li>Choose between tabs **Center** alignment or **Left** alignment (next to the [testing controls](../studio/testing-modes.md#playtest-options)).</li>
|
||||
</ol>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</figure>
|
||||
|
||||
- **Collapse toolbar** — Maximizes space by hiding the toolbar while keeping the mezzanine visible. Hovering over a tab in the mezzanine temporarily reveals the toolbar.
|
||||
- **Compact toolbar** — Makes the toolbar considerably more compact through smaller icons and labels, ideal for laptops or smaller monitors.
|
||||
- **Show labels** — Toggles the text labels below tools on or off.
|
||||
|
||||
### Custom tabs
|
||||
|
||||
Beyond the default tool tabs, you can add **custom tabs** for your specific needs, either through Studio's interface or by editing local `.json` files.
|
||||
|
||||
<Alert severity="info">
|
||||
The tab configuration system is intended for customizing the Studio toolbar using existing controls/widgets and plugins. It's not meant to replace Studio [plugins](./plugins.md) or interactive [widgets](./build-studio-widgets.md).
|
||||
</Alert>
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Studio">
|
||||
The easiest way to create custom tabs is through Studio's workflow.
|
||||
|
||||
1. Click the <kbd>+</kbd> button to the right of the default tabs, then type in a name for the new tab and press <kbd>Enter</kbd>.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Add-Custom-Tab.png" width="800" alt="Button to add custom tab indicated in Studio's mezzanine." />
|
||||
|
||||
<Alert severity="success">
|
||||
Alternatively to creating a new, empty tab, you can duplicate any existing tab by right‑clicking it and selecting **Duplicate tab**. Unlike default tabs, tools within duplicated tabs can be freely modified.
|
||||
</Alert>
|
||||
|
||||
2. Click the button or right‑click in an empty region of the toolbar and select **Add tools**.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Custom-Tab-Add-Tool.png" width="800" alt="Button to add new tool to a custom tab in Studio's toolbar." />
|
||||
|
||||
3. In the popup window, search for a tool and toggle its checkbox to add. New tools appear to the right of other tools, but you can right‑click any tool and select **Move left** or **Move right** to reorder it relative to other tools. You can also insert a divider by right‑clicking in an empty region of the toolbar and selecting **Add divider**.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Custom-Tab-Filled.png" width="800" alt="Custom tab populated with tools." />
|
||||
|
||||
<Alert severity="info">
|
||||
If you need to remove a tool from a custom tab, right‑click it and select **Remove tool**.
|
||||
</Alert>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="JSON">
|
||||
|
||||
Custom tab configurations are saved **locally** on each machine in `.json` format, allowing you to build customized tabs and share them with your team or the community.
|
||||
|
||||
1. Open the custom tabs folder which is stored in a location unaffected by Studio updates.
|
||||
|
||||
- **Windows** — `%LOCALAPPDATA%\Roblox\<userID>\CustomRibbonTabs`
|
||||
- **Mac** — `~/Documents/Roblox/<userID>/CustomRibbonTabs`
|
||||
|
||||
2. In the `CustomRibbonTabs` directory are `.json` files which define the toolbar's structure:
|
||||
|
||||
- The `RibbonLayout.json` file controls the overall ordering and visibility of tabs.
|
||||
|
||||
```json title="RibbonLayout.json"
|
||||
{
|
||||
"TabLayout": [
|
||||
{
|
||||
"Identifier": {
|
||||
"Type": "BuiltIn",
|
||||
"Filename": "HomeTab"
|
||||
},
|
||||
"Visible": true
|
||||
},
|
||||
{
|
||||
```
|
||||
|
||||
- Other `.json` files represent individual tabs and can be named whatever you prefer. Each file's `Name` represents the tab's name as it will appear in Studio.
|
||||
|
||||
```json title="CustomTab.json"
|
||||
{
|
||||
"Name": "Custom",
|
||||
"Controls": [
|
||||
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
3. In the `Controls` array for a tab file, insert various buttons, submenus, and more. Each control's `Id` value must be **unique** within the file.
|
||||
|
||||
The following examples illustrate common elements in a custom tab:
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="IconButton">
|
||||
`IconButton` inserts a button with an optional text label.
|
||||
|
||||
```json title="CustomTab.json"
|
||||
{
|
||||
"Name": "Custom",
|
||||
"Controls": [
|
||||
{
|
||||
"Id": "Select",
|
||||
"Type": "IconButton",
|
||||
"Action": {
|
||||
"Category": "Actions",
|
||||
"DataModel": "Standalone",
|
||||
"ItemId": "Select",
|
||||
"PluginId": "BuilderTools"
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Separator">
|
||||
`Separator` inserts a non-interactable separation line. `Size` options are `Large`, `Medium`, or `Small`.
|
||||
|
||||
```json title="CustomTab.json"
|
||||
{
|
||||
"Name": "Custom",
|
||||
"Controls": [
|
||||
{
|
||||
"Type": "Separator",
|
||||
"Size": "Large"
|
||||
},
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="SplitButton">
|
||||
`SplitButton` inserts a button which reveals a dropdown menu when the small triangle to the right of its icon is pressed.
|
||||
|
||||
```json title="CustomTab.json"
|
||||
{
|
||||
"Name": "Custom",
|
||||
"Controls": [
|
||||
{
|
||||
"Id": "SimpleSplit",
|
||||
"Type": "SplitButton",
|
||||
"Action": {
|
||||
"Category": "Actions",
|
||||
"DataModel": "Standalone",
|
||||
"ItemId": "Select",
|
||||
"PluginId": "BuilderTools"
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"Type": "Column",
|
||||
"Children": [
|
||||
{
|
||||
"Id": "Move",
|
||||
"Type": "Option",
|
||||
"Action": {
|
||||
"Category": "Actions",
|
||||
"DataModel": "Standalone",
|
||||
"ItemId": "Move",
|
||||
"PluginId": "BuilderTools"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": "Scale",
|
||||
"Type": "Option",
|
||||
"Action": {
|
||||
"Category": "Actions",
|
||||
"DataModel": "Standalone",
|
||||
"ItemId": "Scale",
|
||||
"PluginId": "BuilderTools"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": "Rotate",
|
||||
"Type": "Option",
|
||||
"Action": {
|
||||
"Category": "Actions",
|
||||
"DataModel": "Standalone",
|
||||
"ItemId": "Rotate",
|
||||
"PluginId": "BuilderTools"
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="IconButton (Plugin)">
|
||||
`IconButton` can be used to insert a button which links to a [plugin](./plugins.md) through its ID, assuming the plugin, such as [Tailor Swiftly](https://create.roblox.com/store/asset/130172194397869/Tailor-Swiftly), is installed in your version of Studio.
|
||||
|
||||
```json title="CustomTab.json"
|
||||
{
|
||||
"Name": "Custom",
|
||||
"Controls": [
|
||||
{
|
||||
"Id": "PrinceTybalt_Tailor Swiftly",
|
||||
"Type": "IconButton",
|
||||
"Action": {
|
||||
"Category": "Actions",
|
||||
"DataModel": "Edit",
|
||||
"ItemId": "PrinceTybalt_Tailor Swiftly",
|
||||
"PluginId": "130172194397869",
|
||||
"PluginType": "Cloud"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Text">
|
||||
`Text` inserts a basic text label, useful to label groups of other controls in submenus.
|
||||
|
||||
```json title="CustomTab.json"
|
||||
{
|
||||
"Name": "Custom",
|
||||
"Controls": [
|
||||
{
|
||||
"Id": "CustomHeader",
|
||||
"Type": "Text",
|
||||
"Title": "Insert UI"
|
||||
},
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Alert severity="success">
|
||||
Beyond the above examples, you can right-click any default tab and select **Duplicate tab**. This will create a new custom tab and corresponding `.json` file in your local `CustomRibbonTabs` directory which you can inspect to explore how various default tools and menus are constructed.
|
||||
</Alert>
|
||||
|
||||
4. Save the `.json` file and then reload Studio's plugins:
|
||||
|
||||
1. Right-click anywhere in the toolbar or mezzanine and select **Manage tabs**.
|
||||
2. Access the options menu from the popup's upper‑right corner and select **Reload custom tabs**.
|
||||
|
||||
<img src="../assets/studio/general/Manage-Tabs-Popup-Options.png" width="300" alt="Options menu in the Manage Tabs popup." />
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## 3D viewport
|
||||
|
||||
The 3D viewport represents the `Class.Workspace` of a place. From here, you can move the camera around the virtual world, manipulate objects with the mouse, and playtest an experience without leaving Studio.
|
||||
|
||||
<figure>
|
||||
<img
|
||||
src="../assets/studio/general/Editor-Window.jpg"
|
||||
width="100%" alt="An example viewport display of a desert environment with multiple stone pillars. One of the pillars displays movement visual aids from the Move tool." />
|
||||
<figcaption>3D viewport in Roblox Studio</figcaption>
|
||||
</figure>
|
||||
|
||||
### Camera controls
|
||||
|
||||
Inside the viewport, you can move the camera with the following controls.
|
||||
|
||||
<StudioCameraControls components={props.components} />
|
||||
|
||||
### Object selection
|
||||
|
||||
As you hover over parts and models in the viewport, they are outlined to indicate their potential selection. You can select an outlined object by clicking it, or you can select multiple objects by holding <kbd>Shift</kbd>, <kbd>Ctrl</kbd>, or <kbd>⌘</kbd> as you hover over and click them.
|
||||
|
||||
<img src="../assets/studio/general/Editor-Window-Object-Selection.jpg" width="800" alt="A warehouse environment with the stairs and multiple pallet box objects with a blue highlight to signify that they are selected in the 3D viewport."/>
|
||||
|
||||
In more complex environments or when zoomed in, objects will commonly be hidden from your view by other objects in front. To select hidden objects without moving the camera around, hold <kbd>Alt</kbd> or <kbd>⌥</kbd> and click to perform **selection cycling** to the next further object behind the currently selected object.
|
||||
|
||||
<video src="../assets/studio/general/Selection-Cycling.mp4" controls width="800" alt="Video showing selection cycling through a model"></video>
|
||||
|
||||
<Alert severity="info">
|
||||
When one or more objects or [models](../parts/models.md) are selected in the [Explorer](../studio/explorer.md) window, you can select all of their **children** by right-clicking and choosing **Hierarchy** ⟩ **Select Children** from the context menu. Similarly, choosing **Select Parent(s)** selects the **direct parents** of those objects.
|
||||
</Alert>
|
||||
|
||||
To customize the appearance of selection lines and boxes around objects, set your desired options in the **Selection Visualization** section within the **Selection** panel of Studio's settings.
|
||||
|
||||
<img src="../assets/studio/general/Selected-Object-Bounding-Box.jpg" width="800" alt="A warehouse environment with rope object's selection outline and bounding box highlighted." />
|
||||
|
||||
### Visualization options
|
||||
|
||||
In the upper-right corner of the 3D viewport, you can quickly toggle or set common visualization options related to [on‑screen UI](../ui/on-screen-containers.md) overlays, [light sources](../effects/light-sources.md), physics simulation, character [pathfinding](../characters/pathfinding.md), and more. The menu also contains a control for viewing/setting the camera scroll speed.
|
||||
|
||||
<img src="../assets/studio/general/Visualization-Options.png" width="780" alt="A close up view of the 3D viewport with the Visualization Options button indicated in the upper-right corner." />
|
||||
|
||||
## Frequently-used tools
|
||||
|
||||
Commonly used windows include the [Explorer](../studio/explorer.md), the [Properties](../studio/properties.md) window, [Asset Manager](../projects/assets/manager.md), [Toolbox](../projects/assets/toolbox.md), and others.
|
||||
|
||||
### Explorer
|
||||
|
||||
The [Explorer](../studio/explorer.md) window, visible by default and accessible from Studio's **Window** menu or **Home** tab, shows a hierarchical list of every object and service inside the place, collectively referred to as its **data model**. Frequently used services in the hierarchy include `Class.Workspace` which mirrors the [3D viewport](#3d-viewport), as well as `Class.ReplicatedStorage` and `Class.ServerStorage`.
|
||||
|
||||
<img src="../assets/studio/explorer/Parent-Child-Hierarchy.png" width="320" alt="Explorer hierarchy showing Camera, Terrain, and SignModel as children of Workspace; Board and Post as children of SignModel" />
|
||||
|
||||
### Properties
|
||||
|
||||
The [Properties](../studio/properties.md) window, visible by default and accessible from Studio's **Window** menu or **Home** tab, lets you adjust properties of a selected object to change how it looks and behaves. Object properties are divided into sections; for example, a `Class.MeshPart` includes sections like **Appearance** which allows you to change its color, material, transparency, and more.
|
||||
|
||||
<img src="../assets/studio/properties/Sections-Example.png" width="320" />
|
||||
|
||||
At the bottom of the window, you can define custom [attributes](../studio/properties.md#instance-attributes) for an object, similar to its default properties. Attributes and their values are saved with your place/assets and they're an ideal way for team members to experiment with different values during runtime, even if they don't understand the underlying code.
|
||||
|
||||
<img src="../assets/studio/properties/Attributes-Example.png" alt="A close up view of the Attributes section of the Properties window." width="320" />
|
||||
|
||||
### Asset Manager
|
||||
|
||||
The [Asset Manager](../projects/assets/manager.md), accessible from Studio's **Window** menu or **Home** tab, lets you manage places, images, meshes, audio, and more. It also provides a mechanism to bulk import large groups of assets.
|
||||
|
||||
### Toolbox
|
||||
|
||||
The [Toolbox](../projects/assets/toolbox.md), accessible from Studio's **Window** menu or **Home** tab, contains a selection of models, images, meshes, audio, plugins, videos, and fonts made by Roblox or Roblox community members. It also includes all of the creations that you've personally [distributed on the Creator Store](../production/creator-store.md) or those which were distributed by [groups](../projects/groups.md) you belong to.
|
||||
|
||||
<img src="../assets/studio/toolbox/Model-Search-Example.png" width="360" alt="The Toolbox window." />
|
||||
|
||||
### Output
|
||||
|
||||
The [Output](../studio/output.md) window, accessible from Studio's **Window** menu or **Script** tab, displays errors captured from running scripts, messages from Roblox Engine, messages from calls to `Global.LuaGlobals.print()`, and errors from calls to `Global.RobloxGlobals.warn()`.
|
||||
|
||||
### Command Bar
|
||||
|
||||
The **Command Bar**, accessible from Studio's **Script** tab toolbar or the **Window** ⟩ **Script** menu, lets you execute Luau code outside of scripts. To quickly jump to the command bar at any time, press <kbd>Ctrl</kbd><kbd>9</kbd> (Windows) or <kbd>⌘</kbd><kbd>9</kbd> (Mac).
|
||||
|
||||
<BetaAlert betaName="Multi-line Command Bar" leadIn="Most of the features outlined below are in beta and must be enabled through " leadOut="." components={props.components} />
|
||||
|
||||
<img src="../assets/studio/general/Command-Bar.png" width="840" />
|
||||
|
||||
Features include:
|
||||
|
||||
- **Multiline editing** — Press <kbd>Enter</kbd> to insert new lines while typing. The bar starts with 2 lines, grows up to 10 lines as new lines are inserted, and shrinks as lines are deleted. When you're ready to run/execute the contents of the bar, click the **Run** button or use the shortcut <kbd>Ctrl</kbd><kbd>Enter</kbd> (<kbd>⌘</kbd><kbd>Enter</kbd>).
|
||||
|
||||
- **Command history** — The last 10 executed commands are visible by clicking the **History** button and navigating to the **Recent** tab. Clicking on a command in the list loads it into the bar, or you can navigate the list with <kbd>↑</kbd>/<kbd>↓</kbd> and insert the highlighted command with <kbd>Enter</kbd>. Alternatively, you can scrub through commands with <Typography noWrap><kbd>Ctrl</kbd>/<kbd>⌘</kbd> + <kbd>↑</kbd>/<kbd>↓</kbd></Typography> when the command bar is selected.
|
||||
|
||||
- **Saved commands** — You can explicitly save commands with the **Save** button or the default shortcut <kbd>Ctrl</kbd><kbd>B</kbd> (<kbd>⌘</kbd><kbd>B</kbd>). Saved commands can be accessed through the **Saved** tab in the popup list, and the mechanics of loading saved commands from the list are the same as those in the command history.
|
||||
|
||||
- **Script Editor integration** — The command bar is an embedded script editor and supports a wide subset of Studio's [Script Editor](./script-editor.md) features, including [autocomplete](./script-editor.md#autocomplete-features), Luau [linting](https://luau.org/lint), [go to declaration](./script-editor.md#go-to-declaration), [function filter](./script-editor.md#script-function-filter), [Code Assist](./script-editor.md#code-assist), and [multi‑cursor](./script-editor.md#multi-cursor).
|
||||
|
||||
## Layout customization
|
||||
|
||||
Studio's drag-and-drop interface lets you easily customize window layout to best suit your workflows.
|
||||
|
||||
### Reposition windows
|
||||
|
||||
You can reposition any window by click-dragging its **header bar**. As you begin dragging the window, the interface reveals **empty docking area** regions. If you drag the mouse pointer into any empty region, a floating **position selector** appears in that region. Dragging the pointer over the "center" of the floating selector targets the empty region as the dragged window's destination, indicated by the region darkening and becoming outlined.
|
||||
|
||||
<figure>
|
||||
<img src="../assets/studio/general/Docking-Position-Selector-Empty.png" width="880" alt="Mouse pointer hovering over the 'center' icon of the position selector in an empty docking area, showing that region as the dragged window's destination." />
|
||||
<figcaption>Mouse pointer hovering over the "center" icon of the position selector in an empty docking area</figcaption>
|
||||
</figure>
|
||||
|
||||
If you drag the mouse pointer into a **populated** region such as the 3D viewport, a floating position selector appears with multiple options for the window's destination. For example, dragging the pointer over the "left" icon will position the window on the region's left side.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Viewport left">
|
||||
<img src="../assets/studio/general/Docking-Position-Selector-Left.png" width="880" height="520" alt="Mouse pointer hovering over the 'left half' icon of the position selector in a populated region, showing the left side of the region as the dragged window's destination." />
|
||||
</TabItem>
|
||||
<TabItem label="Viewport right">
|
||||
<img src="../assets/studio/general/Docking-Position-Selector-Right.png" width="880" height="520" alt="Mouse pointer hovering over the 'right half' icon of the position selector in a populated region, showing the right side of the region as the dragged window's destination." />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Group windows
|
||||
|
||||
If you drag a window into a **populated** region and choose the "center" icon of the [position selector](#reposition-windows), the dragged window will group into that region as a tab. This allows you to set up tab groups of commonly used windows.
|
||||
|
||||
<figure>
|
||||
<img src="../assets/studio/general/Docking-Grouped-Tabs.png" width="320" alt="An example of an Explorer window if you choose the center icon of the position selection. It includes three tabs at the bottom of the window: the Explorer window, the Properties window, and the Terrain Editor window." />
|
||||
<figcaption>Three windows grouped together as tabs</figcaption>
|
||||
</figure>
|
||||
|
||||
### Pin windows
|
||||
|
||||
To maximize screen space for the 3D viewport, you can **pin** windows (or an entire [group](#group-windows) of windows) to the edges of the overall Studio window. Once pinned, you can temporarily open any window by clicking its tab — this does not disturb other windows, and the expanded window will automatically collapse when you click in another window or click its tab again.
|
||||
|
||||
<figure>
|
||||
<img src="../assets/studio/general/Docking-Pinned-Tabs.png" width="800" alt="An example 3D viewport where the Explorer, Properties, and Terrain Editor windows are pinned to the right of the Studio window." />
|
||||
<figcaption>Three windows pinned to the right side of the Studio window</figcaption>
|
||||
</figure>
|
||||
|
||||
To pin a window or an entire [group](#group-windows) of windows, click the "collapse" button. Alternatively, to un‑pin a pinned window/group, open it by clicking its tab, then click the "expand" button.
|
||||
|
||||
<img src="../assets/studio/general/Docking-Expand-Collapse.png" width="320" alt="A close up view of the Explorer window with the Collapse button highlighted." />
|
||||
|
||||
### Float windows
|
||||
|
||||
To float a window freely of other windows, simply drag‑and‑drop it without selecting any icon from the floating [position selector](#reposition-windows).
|
||||
Loading…
Add table
Add a link
Reference in a new issue