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
58
.cursor/rules/roblox/en-us/physics/adaptive-timestepping.md
Normal file
58
.cursor/rules/roblox/en-us/physics/adaptive-timestepping.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
title: Adaptive timestepping
|
||||
description: Adaptive timestepping automatically assigns physical parts to varying simulation timesteps.
|
||||
---
|
||||
|
||||
The Roblox physics engine simulates all parts inside the 3D workspace through Newton's second law of motion. This law of motion is solved over time via **timesteps** and a single timestep is done within a **worldstep** in Roblox.
|
||||
|
||||
By default, Roblox simulates physics at 240 Hz. Given cycles of approximately 60 frames per second, around 4 worldsteps are advanced per frame. With **adaptive timestepping**, the physics engine automatically assigns parts to three "solver islands" by varying their simulation timestep, with an emphasis on 60 Hz for best performance. However, parts that are "harder" to solve will use a faster timestep like 240 Hz to ensure physical stability.
|
||||
|
||||
<img src="../assets/physics/adaptive-timestepping/Diagram-Labels.png" alt="" width="100%" />
|
||||
|
||||
Assignment criterions are subject to change, but parts assigned to the 240 Hz island include [assemblies](../physics/assemblies.md) with high velocity values, high acceleration values, and complex mechanisms that are hard to solve.
|
||||
|
||||
## Enable adaptive mode
|
||||
|
||||
To enable adaptive timestepping in Studio:
|
||||
|
||||
1. In the **Explorer** window, select the **Workspace** object.
|
||||
|
||||
<img src="../assets/studio/explorer/Workspace.png" alt="" width="320" />
|
||||
|
||||
2. In the **Properties** window, locate **PhysicsSteppingMethod** and select **Adaptive**.
|
||||
|
||||
<img src="../assets/physics/adaptive-timestepping/PhysicsSteppingMethod-Adaptive.png" alt="" width="320" />
|
||||
|
||||
To observe the timestepping process in action, you can open the Studio **Microprofiler** (<kbd>Ctrl</kbd><kbd>F6</kbd>; <kbd>⌘</kbd><kbd>F6</kbd>). Once the experience is running, press <kbd>Ctrl</kbd><kbd>P</kbd> (<kbd>⌘</kbd><kbd>P</kbd>) to pause at the current frame.
|
||||
|
||||
Under the scope named **physicsStepped**, observe that the scope name of **worldStep** now reads **worldStep - Adaptive**.
|
||||
|
||||
<img src="../assets/physics/adaptive-timestepping/Adaptive-Timestepping-Microprofiler-A.png" alt="" width="80%" />
|
||||
|
||||
Hovering your cursor above **LDLPGSSolver::solve** will reveal the status of how many islands belong in each frequency bucket; **1dt Islands** (240 Hz), **2dt Islands** (120 Hz) and **4dt Islands** (60 Hz).
|
||||
|
||||
<img src="../assets/physics/adaptive-timestepping/Adaptive-Timestepping-Microprofiler-B.png" alt="" width="80%" />
|
||||
|
||||
## Debug visualization
|
||||
|
||||
During testing, it may be useful to visualize frequencies for simulated parts. To enable this option:
|
||||
|
||||
1. Open [Studio Settings](../studio/setup.md#customization).
|
||||
2. From the **Physics** tab, enable **Are Timesteps Shown**.
|
||||
|
||||
Once enabled, simulated parts will be outlined by their current simulation rate. If a part stops being simulated, either via the [sleep system](../physics/sleep-system.md) or a network ownership change, the part will no longer be outlined.
|
||||
|
||||
<img src="../assets/physics/adaptive-timestepping/Diagram-Labels.png" alt="" width="100%" />
|
||||
|
||||
<figure>
|
||||
<video src="../assets/physics/adaptive-timestepping/Adaptive-Timestepping.mp4" controls width="100%"></video>
|
||||
<figcaption>Simulated parts outlined by the color representing their current simulation rate</figcaption>
|
||||
</figure>
|
||||
|
||||
## Fixed-rate scenarios
|
||||
|
||||
Adaptive timestepping can improve physics performance by up to 2.5 times and it is recommended in most cases. However, some experiences should use **Fixed** mode (240 Hz), including:
|
||||
|
||||
Experiences that require highly accurate simulations and stability, such as racing games, "destruction" simulations, or experiences featuring complex mechanisms like tanks.
|
||||
|
||||
Simulations where most parts default to the 240 Hz solver island (red outlines during [debugging](#debug-visualization)). When 240 Hz islands interact with islands of different frequencies (60–120 Hz), those islands are converted to 240 Hz with an overhead that may negate any performance gains resulting from adaptive timestepping.
|
||||
127
.cursor/rules/roblox/en-us/physics/assemblies.md
Normal file
127
.cursor/rules/roblox/en-us/physics/assemblies.md
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
---
|
||||
title: Assemblies
|
||||
description: Explains physical assemblies and how they behave in Roblox's rigid body physics engine.
|
||||
---
|
||||
|
||||
An **assembly** is one or more [parts](../parts/index.md) welded by a rigid `Class.WeldConstraint|WeldConstraint` or connected through moveable joints, like `Class.Motor6D|Motor6Ds`. You can group an assembly of parts in a [model](../parts/models.md) container to quickly organize the parts and related objects as a single asset.
|
||||
|
||||
<Grid container spacing={0}>
|
||||
<Grid item XSmall={6} XLarge={3}>
|
||||
<img src="../assets/physics/assemblies/Assembly-Example-Block.png" alt="A light blue cube against a dark blue background that represents an assembly of 1 part." width="100%" />
|
||||
<figcaption>1 assembly; 1 part</figcaption>
|
||||
</Grid>
|
||||
<Grid item XSmall={6} XLarge={3}>
|
||||
<img src="../assets/physics/assemblies/Assembly-Example-Avatar.png" alt="A humanoid character model against a dark blue background that represents an assembly of 18 parts." width="100%" />
|
||||
<figcaption>1 assembly; 18 parts</figcaption>
|
||||
</Grid>
|
||||
<Grid item XSmall={12} XLarge={6}>
|
||||
<img src="../assets/physics/assemblies/Assembly-Example-Ship.png" alt="A pirate that represents an assemble of 179 parts." width="100%" />
|
||||
<figcaption>1 assembly; 179 parts</figcaption>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<br />
|
||||
|
||||
From a physics perspective, an assembly is considered a single **rigid body**, meaning no force can push or pull the connected parts from each other, and they will move as a single unit. All forces applied to a specific `Class.BasePart` are applied to its assembly — for instance, `Class.BasePart:ApplyImpulse()` applies impulse to the assembly at `Class.BasePart.AssemblyCenterOfMass`.
|
||||
|
||||
<Alert severity="info">
|
||||
The joints that combine multiple parts into assemblies are only active in the `Class.Workspace` or another `Class.WorldModel` instance. If the parts are stored elsewhere, all of the welds/connections that combine parts into assemblies will be non-functional.
|
||||
</Alert>
|
||||
|
||||
<Alert severity="success">
|
||||
To view colored outlines around parts in order to visualize single rigid body assemblies, toggle on **Assemblies** from the [Visualization Options](../studio/ui-overview.md#visualization-options) widget in the upper‑right corner of the 3D viewport.
|
||||
</Alert>
|
||||
|
||||
## Assembly properties
|
||||
|
||||
The following `Class.BasePart` properties show data regarding its assembly. Their values will be the same for any part in the same assembly, so it doesn't matter which part you use.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Property</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>`Class.BasePart.AssemblyLinearVelocity`</td>
|
||||
<td>The linear velocity vector of the part's assembly. Setting the velocity directly may lead to unrealistic motion, so usage of a `Class.VectorForce` or `Class.LinearVelocity` constraint is preferred, or `Class.BasePart:ApplyImpulse()` for an instantaneous change in linear velocity.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Class.BasePart.AssemblyAngularVelocity`</td>
|
||||
<td>The angular velocity vector of the part's assembly. Setting the velocity directly may lead to unrealistic motion, so usage of a `Class.Torque` or `Class.AngularVelocity` constraint is preferred, or `Class.BasePart:ApplyAngularImpulse()` for an instantaneous change in angular velocity.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Class.BasePart.AssemblyCenterOfMass`</td>
|
||||
<td>A read-only position calculated via the mass and position of all the parts in the assembly. A force applied to the center of mass will not cause angular acceleration, only linear.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Class.BasePart.AssemblyMass`</td>
|
||||
<td>The sum of the `Class.BasePart.Mass` of all parts in the assembly. If the assembly has an anchored part, the assembly's mass is considered infinite.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>`Class.BasePart.AssemblyRootPart`</td>
|
||||
<td>The part automatically chosen to represent the assembly's [root part](#assembly-root-part).</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Assembly root part
|
||||
|
||||
Every assembly has a **root part** indicated by its `Class.BasePart.AssemblyRootPart|AssemblyRootPart` property. This is the part that doesn't move when `Class.Motor6D` transforms are updated, as well as the part used to keep consistent physics replication and network ownership.
|
||||
|
||||
You cannot explicitly set the root part, but the following factors affect probability from highest to lowest:
|
||||
|
||||
<Grid container spacing={2}>
|
||||
<Grid item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Arrow-Higher.png" alt="" width="50" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
An `Class.BasePart.Anchored|Anchored` part will always be assigned as the root part.
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Arrow-High.png" alt="" width="50" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Parts with `Class.BasePart.Massless|Massless` set to **false** (default) take precedence.
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Arrow-Low.png" alt="" width="50" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Higher `Class.BasePart.RootPriority|RootPriority` values take precedence.
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item XSmall={2} Medium={1} Large={1} XLarge={1}><img src="../assets/misc/Arrow-Lower.png" alt="" width="50" style={{float:"right"}} /></Grid>
|
||||
<Grid item XSmall={10} Medium={11} Large={11} XLarge={11} style={{marginTop:"4px"}}>
|
||||
Precedence based on the part's size, with multipliers for parts with specific names.
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
## Anchoring behavior
|
||||
|
||||
When one of an assembly's parts is anchored, that part becomes the root part and all of the other parts become implicitly anchored with it. The following sequence illustrates this behavior.
|
||||
|
||||
1. Below, four parts are welded together with `Class.WeldConstraint|WeldConstraints` (green bars) to form a single assembly, as indicated by the matching colored outlines.
|
||||
|
||||
<figure>
|
||||
<img src="../assets/physics/assemblies/Assembly-Anchor-Diagram-1.png" width="720" />
|
||||
<figcaption>Four parts welded to become a single assembly</figcaption>
|
||||
</figure>
|
||||
|
||||
2. If just **one** part in the assembly is anchored, the assembly will not change, other than the root part potentially changing (the anchored part always has the highest [priority](#assembly-root-part) for becoming the root part).
|
||||
|
||||
<figure>
|
||||
<img src="../assets/physics/assemblies/Assembly-Anchor-Diagram-2.png" width="720" />
|
||||
<figcaption>Anchored part (as indicated with an anchor icon) becomes the new root part</figcaption>
|
||||
</figure>
|
||||
|
||||
3. If more than one part is anchored, the assembly will **split**. Below, both the left and top parts are anchored, so the original assembly splits into two assemblies as shown by the colored outlines. Also, the `Class.WeldConstraint` between the two assemblies deactivates, since you cannot have an active weld between two anchored assemblies.
|
||||
|
||||
<figure>
|
||||
<img src="../assets/physics/assemblies/Assembly-Anchor-Diagram-3.png" width="720" />
|
||||
<figcaption>Two assemblies with anchored parts as their respective root parts</figcaption>
|
||||
</figure>
|
||||
|
||||
<Alert severity="warning">
|
||||
If you want to anchor all parts in an assembly, you only need to anchor the assembly's root part. Anchoring all parts is actually less performant, as it creates more assemblies.
|
||||
</Alert>
|
||||
107
.cursor/rules/roblox/en-us/physics/character-controllers.md
Normal file
107
.cursor/rules/roblox/en-us/physics/character-controllers.md
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
---
|
||||
title: Character controllers
|
||||
description: Controller instances can be used as a component in a custom character implementation.
|
||||
---
|
||||
|
||||
The `Class.ControllerManager` instance manages simulated motion control for its assigned `Class.ControllerManager.RootPart|RootPart`. Along with `Class.ControllerPartSensor|ControllerPartSensors`, it can be used to build a physics‑based character controller.
|
||||
|
||||
## Core setup
|
||||
|
||||
`Class.ControllerManager` requires a `Class.BasePart` to use as its root. Movement forces and part sensing will be on this part.
|
||||
|
||||
1. Choose a `Class.Part` or `Class.MeshPart` and name it **RootPart**.
|
||||
2. Group the part as a `Class.Model` instance for organization along with the other components.
|
||||
3. Add a `Class.ControllerManager` instance to the model. If **ControllerManager** doesn't initially appear in the object insertion menu, **uncheck** "Show only recommended objects" in the menu's [insertion settings](../studio/explorer.md#insert-and-parent).
|
||||
|
||||
<img src="../assets/physics/character-controller/Explorer-Core-Setup.png" width="320" alt="ControllerManager and RootPart inside a model." />
|
||||
|
||||
### Sensor setup
|
||||
|
||||
A `Class.ControllerPartSensor` detects parts with the same code the `Class.Humanoid` uses for detecting floors and ladders.
|
||||
|
||||
1. Insert a `Class.ControllerPartSensor` as a child of **RootPart** and rename it **GroundSensor** for easier identification of its purpose. Then, in the [Properties](../studio/properties.md) window, set its `Class.ControllerPartSensor.SearchDistance|SearchDistance` property to **2** but leave its `Class.ControllerPartSensor.SensorMode|SensorMode` as **Floor**.
|
||||
|
||||
<img src="../assets/physics/character-controller/Explorer-RootPart-GroundSensor.png" width="320" alt="GroundSensor as child of RootPart" /><br />
|
||||
<img src="../assets/physics/character-controller/Properties-GroundSensor.png" width="320" alt="" />
|
||||
|
||||
2. Insert another `Class.ControllerPartSensor` as a child of **RootPart** and rename it **ClimbSensor**. Then, in the [Properties](../studio/properties.md) window, set its `Class.ControllerPartSensor.SearchDistance|SearchDistance` property to **1** and its `Class.ControllerPartSensor.SensorMode|SensorMode` to **Ladder**.
|
||||
|
||||
<img src="../assets/physics/character-controller/Explorer-RootPart-ClimbSensor.png" width="320" alt="ClimbSensor as child of RootPart" /><br />
|
||||
<img src="../assets/physics/character-controller/Properties-ClimbSensor.png" width="320" alt="" />
|
||||
|
||||
### Controller setup
|
||||
|
||||
Controller instances like `Class.GroundController` and `Class.ClimbController` tell the managed part how to interact with the world, working alongside the sensors you configured during the [sensor setup](#sensor-setup).
|
||||
|
||||
1. Insert both a `Class.GroundController` and `Class.ClimbController` as children of the `Class.ControllerManager`.
|
||||
|
||||
<img src="../assets/physics/character-controller/Explorer-Controllers.png" width="320" alt="GroundController and ClimbController as children of ControllerManager." />
|
||||
|
||||
2. Select the new `Class.GroundController` instance and then, in the [Properties](../studio/properties.md) window, set its `Class.GroundController.GroundOffset|GroundOffset` property to a value at which the managed part should "levitate" above the ground. It's important that this value is **less** than the value of `Class.ControllerPartSensor.SearchDistance|SearchDistance` for the [GroundSensor](#sensor-setup), since that sensor will deactivate if it loses sense of the ground and effectively stop its forces on the part.
|
||||
|
||||
<img src="../assets/physics/character-controller/Properties-GroundController.png" width="320" alt="" />
|
||||
|
||||
### Link references
|
||||
|
||||
To complete the core setup, you'll need to link various properties of the `Class.ControllerManager` instance to objects within the main `Class.Model`.
|
||||
|
||||
1. Select the `Class.ControllerManager` instance.
|
||||
|
||||
<img src="../assets/physics/character-controller/Explorer-ControllerManager.png" width="320" alt="ControllerManager selected in Explorer window." />
|
||||
|
||||
1. In the [Properties](../studio/properties.md) window, click each of the following properties and then, back in the [Explorer](../studio/explorer.md) window, click the respective instance to complete the link.
|
||||
|
||||
1. Link the `Class.ControllerManager.ActiveController|ActiveController` property to the **GroundController** instance.
|
||||
1. Link the `Class.ControllerManager.RootPart|RootPart` property to the part you named **RootPart**.
|
||||
1. Link the `Class.ControllerManager.ClimbSensor|ClimbSensor` property to the **ClimbSensor** instance.
|
||||
1. Link the `Class.ControllerManager.GroundSensor|GroundSensor` property to the **GroundSensor** instance.
|
||||
|
||||
<img src="../assets/physics/character-controller/Linking-References.png" width="680" alt="ControllerManager properties linked to instances within overall model" />
|
||||
|
||||
### Test
|
||||
|
||||
With [sensors](#sensor-setup) and [controllers](#controller-setup) in place, and with [references linked](#link-references), you can test the controller in Studio.
|
||||
|
||||
1. [Initiate a playtest](../studio/testing-modes.md#playtesting) using the **Run** mode (<kbd>F8</kbd>) since you don't need to insert your avatar character in this scenario.
|
||||
2. **RootPart** should levitate above the ground at the `Class.GroundController.GroundOffset` value you set in [Adding Controllers](#controller-setup). It should also rotate to align with the `Class.ControllerManager.FacingDirection` vector.
|
||||
|
||||
<img src="../assets/physics/character-controller/Testing-Labeled.jpg" width="800" alt="Character levitating above ground at GroundOffset, facing in direction of FacingDirection vector." />
|
||||
|
||||
3. Experiment with different movement and facing directions by changing the `Class.ControllerManager.MovingDirection|MovingDirection` and `Class.ControllerManager.FacingDirection|FacingDirection` vectors of the `Class.ControllerManager` during runtime. Also experiment with different properties of the `Class.GroundController` instance such as `Class.GroundController.AccelerationTime|AccelerationTime`, `Class.GroundController.DecelerationTime|DecelerationTime`, and `Class.GroundController.GroundOffset|GroundOffset`.
|
||||
|
||||
<Grid container spacing={4}>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/physics/character-controller/Properties-Testing-ControllerManager.png" width="320" alt="ControllerManager properties for moving and facing direction are highlighted." />
|
||||
<figcaption>ControllerManager</figcaption>
|
||||
</figure>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<figure>
|
||||
<img src="../assets/physics/character-controller/Properties-Testing-GroundController.png" width="320" alt="GroundController properties for acceleration, deceleration, and ground offset are highlighted." />
|
||||
<figcaption>GroundController</figcaption>
|
||||
</figure>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Alert severity="warning">
|
||||
Remember that `Class.GroundController.GroundOffset|GroundOffset` must be **less** than the value of `Class.ControllerPartSensor.SearchDistance|SearchDistance` for the [GroundSensor](#sensor-setup), since that sensor will deactivate if it loses sense of the ground and effectively stop its forces on the part. This will cause a bouncing effect as gravity and the `Class.GroundController` repeatedly swap control of the part.
|
||||
</Alert>
|
||||
|
||||
## Custom sensors
|
||||
|
||||
The `Class.ControllerPartSensor.SensorMode` options of `Enum.SensorMode|Floor` and `Enum.SensorMode|Ladder` run the exact `Class.Humanoid` sensor code, letting you use them for backwards compatibility. However, you can also customize how and when walkable and climbable parts are detected, ultimately changing when the managed part walks/climbs.
|
||||
|
||||
1. Switch the `Class.ControllerPartSensor.UpdateType` from **OnRead** to **Manual**.
|
||||
|
||||
- **OnRead** triggers the output properties to update corresponding to your `Class.ControllerPartSensor.SensorMode|SensorMode` every time you read them. It essentially puts the sensor in a "read‑only" mode where anything you write to these properties becomes overwritten by its internal sensing behavior.
|
||||
- **Manual** turns off the internal sensing behavior. The output properties are free for you to write however you like and the `Class.ControllerPartSensor.SensorMode|SensorMode` does nothing.
|
||||
|
||||
2. Create a script that performs your own sensing logic and writes the outputs to your sensor output properties. Typically you'll use a spatial query such as `Class.WorldRoot:Raycast()` or `Class.WorldRoot:Blockcast()` which returns a `Datatype.RaycastResult`. Your script can then take the result properties and set them on the sensor equivalents:
|
||||
|
||||
- `Datatype.RaycastResult.Instance` → `Class.ControllerPartSensor.SensedPart`
|
||||
- `Datatype.RaycastResult.Normal` → `Class.ControllerPartSensor.HitNormal`
|
||||
|
||||
Note that you'll need to manage how often your queries run and update their sensor instance.
|
||||
|
||||
3. The `Class.ControllerManager` will continue to use the sensors it has been assigned, taking the data you pass to it.
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
title: AlignOrientation
|
||||
description: The AlignOrientation constraint applies torque to align two attachments, or to align one attachment with a goal orientation.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mover constraints, including `Class.AlignOrientation`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
The `Class.AlignOrientation` constraint applies torque to align two attachments, or to align one attachment with a goal orientation. As indicated by the name, it only affects the **orientation** of the attachments, not their position (to align attachments **positionally**, see [AlignPosition](../../physics/constraints/align-position.md)).
|
||||
|
||||
<video controls src="../../assets/physics/constraints/AlignOrientation-Demo.mp4" width="90%" alt="Demo video of AlignOrientation constraint"></video>
|
||||
|
||||
<Alert severity="warning">
|
||||
By default, the constraint only applies torque to `Class.Constraint.Attachment0|Attachment0`, although this behavior can be controlled through `Class.AlignOrientation.ReactionTorqueEnabled|ReactionTorqueEnabled`.
|
||||
</Alert>
|
||||
|
||||
## Affected axes
|
||||
|
||||
The axes affected by torque are controlled through the constraint's `Class.AlignOrientation.AlignType|AlignType` property. When set to `Enum.AlignType|PrimaryAxisParallel`, `Enum.AlignType|PrimaryAxisPerpendicular` or `Enum.AlignType|PrimaryAxisLookAt`, torque will only occur when the primary axes become misaligned. Otherwise, the constraint will apply torque about all 3 axes to achieve alignment.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/AlignOrientation-AlignType-AllAxes.mp4" alt="Video showing AlignType set to AllAxes"></video>
|
||||
<figcaption>AlignType = **AllAxes**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/AlignOrientation-AlignType-PrimaryAxisParallel.mp4" alt="Video showing AlignType set to PrimaryAxisParallel"></video>
|
||||
<figcaption>AlignType = **PrimaryAxisParallel**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Reactionary torque
|
||||
|
||||
By default, the constraint only applies torque to `Class.Constraint.Attachment0|Attachment0` while `Class.Constraint.Attachment1|Attachment1` remains unaffected. If desired, torque can be applied to both attachments in **equal and opposite directions** by enabling `Class.AlignOrientation.ReactionTorqueEnabled|ReactionTorqueEnabled`.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/AlignOrientation-ReactionTorqueEnabled-False.mp4" alt="Video showing ReactionTorqueEnabled set to false"></video>
|
||||
<figcaption>ReactionTorqueEnabled = **false**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/AlignOrientation-ReactionTorqueEnabled-True.mp4" alt="Video showing ReactionTorqueEnabled set to true"></video>
|
||||
<figcaption>ReactionTorqueEnabled = **true**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Torque magnitude
|
||||
|
||||
You can configure the `Class.AlignOrientation` constraint to apply the maximum torque that constraints allow through the `Class.AlignOrientation.RigidityEnabled|RigidityEnabled` property. When true, the physics solver reacts as quickly as possible to complete the alignment. When false, the torque is determined by `Class.AlignOrientation.MaxTorque|MaxTorque`, `Class.AlignOrientation.MaxAngularVelocity|MaxAngularVelocity`, and `Class.AlignOrientation.Responsiveness|Responsiveness`.
|
||||
|
||||
## Attachment mode
|
||||
|
||||
The `Class.AlignOrientation.Mode|Mode` property specifies whether the constraint uses **one** or **two** attachments in calculating its goal. By default, this is **TwoAttachment**, meaning that the constraint attempts to match the orientation of `Class.Constraint.Attachment0|Attachment0` with the orientation of `Class.Constraint.Attachment1|Attachment1`, disregarding `Class.AlignOrientation.CFrame|CFrame`, `Class.AlignOrientation.PrimaryAxis|PrimaryAxis`, and `Class.AlignOrientation.SecondaryAxis|SecondaryAxis`.
|
||||
|
||||
If set to **OneAttachment**, the constraint disregards `Class.Constraint.Attachment1|Attachment1` and attempts to match the orientation of `Class.Constraint.Attachment0|Attachment0` with the orientation of `Class.AlignOrientation.CFrame|CFrame`, or match the attachment's `Class.Attachment.Axis|Axis` and `Class.Attachment.SecondaryAxis|SecondaryAxis` with the constraint's `Class.AlignOrientation.PrimaryAxis|PrimaryAxis` and `Class.AlignOrientation.SecondaryAxis|SecondaryAxis` properties respectively.
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
title: AlignPosition
|
||||
description: The AlignPosition constraint applies force to move two attachments together, or to move one attachment to a goal position.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mover constraints, including `Class.AlignPosition`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
An `Class.AlignPosition` constraint applies force to move two attachments together, or to move one attachment to a goal position. As indicated by the name, it only affects the **position** of the attachments, not their orientation (to align attachments by **orientation**, see [AlignOrientation](../../physics/constraints/align-orientation.md)).
|
||||
|
||||
<video controls src="../../assets/physics/constraints/AlignPosition-Demo.mp4" width="90%" alt="Demo video of AlignPosition constraint"></video>
|
||||
|
||||
<Alert severity="warning">
|
||||
By default, the constraint only applies force to `Class.Constraint.Attachment0|Attachment0`, although this behavior can be controlled through `Class.AlignPosition.ReactionForceEnabled|ReactionForceEnabled`.
|
||||
</Alert>
|
||||
|
||||
## Force location
|
||||
|
||||
By default, force is applied to the parent of `Class.Constraint.Attachment0|Attachment0` at that attachment's location, meaning that if the parent's center of mass is not aligned with the direction of the force, torque will be applied as well as force. Alternatively, force can be applied to the parents' center of mass by toggling on `Class.AlignPosition.ApplyAtCenterOfMass|ApplyAtCenterOfMass`.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/AlignPosition-ApplyAtCenterOfMass-False.mp4" alt="Video showing ApplyAtCenterOfMass set to false"></video>
|
||||
<figcaption>ApplyAtCenterOfMass = **false**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/AlignPosition-ApplyAtCenterOfMass-True.mp4" alt="Video showing ApplyAtCenterOfMass set to true"></video>
|
||||
<figcaption>ApplyAtCenterOfMass = **true**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Reactionary force
|
||||
|
||||
By default, the constraint only applies force to `Class.Constraint.Attachment0|Attachment0` while `Class.Constraint.Attachment1|Attachment1` remains unaffected. If desired, force can be applied to both attachments in **equal and opposite directions** by enabling `Class.AlignPosition.ReactionForceEnabled|ReactionForceEnabled`.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/AlignPosition-ReactionForceEnabled-False.mp4" alt="Video showing ReactionForceEnabled set to false"></video>
|
||||
<figcaption>ReactionForceEnabled = **false**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/AlignPosition-ReactionForceEnabled-True.mp4" alt="Video showing ReactionForceEnabled set to true"></video>
|
||||
<figcaption>ReactionForceEnabled = **true**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Force magnitude
|
||||
|
||||
You can configure the `Class.AlignPosition` constraint to apply the maximum force that constraints allow through the `Class.AlignPosition.RigidityEnabled|RigidityEnabled` property. When true, the physics solver reacts as quickly as possible to complete the alignment. When false, the force is determined by `Class.AlignPosition.MaxForce|MaxForce`, `Class.AlignPosition.MaxVelocity|MaxVelocity`, and `Class.AlignPosition.Responsiveness|Responsiveness`.
|
||||
|
||||
## Attachment mode
|
||||
|
||||
The `Class.AlignPosition.Mode|Mode` property specifies whether the constraint uses **one** or **two** attachments in calculating its goal. By default, this is `Enum.PositionAlignmentMode|TwoAttachment`, meaning that the constraint disregards `Class.AlignPosition.Position|Position` and attempts to move `Class.Constraint.Attachment0|Attachment0` to the position of `Class.Constraint.Attachment1|Attachment1`. If set to `Enum.PositionAlignmentMode|OneAttachment`, the constraint disregards `Class.Constraint.Attachment1|Attachment1` and attempts to move `Class.Constraint.Attachment0|Attachment0` to `Class.AlignPosition.Position|Position`.
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
title: AngularVelocity
|
||||
description: The AngularVelocity constraint applies torque on an assembly to maintain a constant angular velocity.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mover constraints, including `Class.AngularVelocity`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
An `Class.AngularVelocity` constraint applies torque on an assembly to maintain a constant angular velocity.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/AngularVelocity-Demo.mp4" width="90%" alt="Demo video of AngularVelocity constraint"></video>
|
||||
|
||||
<Alert severity="warning">
|
||||
The `Class.AngularVelocity` constraint applies torque that attempts to maintain a **constant** angular velocity. If you want to control the amount of torque applied, use a [Torque](../../physics/constraints/torque.md) constraint. Alternatively, if you only need **initial** angular velocity, set the `Class.BasePart.AssemblyAngularVelocity|AssemblyAngularVelocity` method directly on the assembly.
|
||||
</Alert>
|
||||
|
||||
## Relativity
|
||||
|
||||
Application of velocity can be controlled through the constraint's `Class.AngularVelocity.RelativeTo|RelativeTo` property. If set to `Enum.ActuatorRelativeTo|World`, the angular velocity vector is used as is. If set to `Enum.ActuatorRelativeTo|Attachment1` and the constraint's `Class.Constraint.Attachment1|Attachment1` property is set to another attachment, the angular velocity will be affected by that of the other attachment as seen by how the upper-left red part's velocity affects the attached blue part's velocity.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/AngularVelocity-RelativeTo-World.mp4" alt="Video showing relative behavior set to world space"></video>
|
||||
<figcaption>RelativeTo = **World**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/AngularVelocity-RelativeTo-Attachment1.mp4" alt="Video showing relative behavior set to Attachment1"></video>
|
||||
<figcaption>RelativeTo = **Attachment1**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
<Alert severity="info">
|
||||
Setting `Class.AngularVelocity.RelativeTo|RelativeTo` to `Enum.ActuatorRelativeTo|Attachment1` also exposes the `Class.AngularVelocity.ReactionTorqueEnabled|ReactionTorqueEnabled` property.
|
||||
</Alert>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
title: BallSocket
|
||||
description: BallSocketConstraint forces its two attachments into the same position and allows them to freely rotate about all three axes, with optional limits to restrict both tilt and twist.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mechanical constraints, including `Class.BallSocketConstraint`, see [Mechanical constraints](../../physics/mechanical-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.BallSocketConstraint` forces its two attachments into the same position and allows them to freely rotate about all three axes. However, you can enable limits to restrict both tilt and twist.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/BallInSocket-Demo.mp4" width="90%" alt="Demo video of BallSocketConstraint"></video>
|
||||
|
||||
## Limits
|
||||
|
||||
You can set limits to restrict both **tilt** and **twist** of a ball socket, similar to how a human's head can tilt and turn within a limited axial range. Enabling the `Class.BallSocketConstraint.LimitsEnabled|LimitsEnabled` property exposes the `Class.BallSocketConstraint.UpperAngle|UpperAngle` value to restrict **tilt** within a cone; it also exposes the `Class.BallSocketConstraint.TwistLimitsEnabled|TwistLimitsEnabled` property which, when enabled, lets you restrict **twist** rotation through the `Class.BallSocketConstraint.TwistLowerAngle|TwistLowerAngle` and `Class.BallSocketConstraint.TwistUpperAngle|TwistUpperAngle` limits.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/BallInSocket-Limits-Tilt.mp4" alt="Video showing limits when UpperAngle is set to 30 degrees"></video>
|
||||
<figcaption>UpperAngle = **30**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/BallInSocket-Limits-Twist.mp4" alt="Video showing limits when TwistLimitsEnabled is set to true"></video>
|
||||
<figcaption>TwistLimitsEnabled = **true**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
Enabling `Class.BallSocketConstraint.LimitsEnabled|LimitsEnabled` also exposes the `Class.BallSocketConstraint.Restitution|Restitution` value which defines the elasticity of the attachments at their tilt and/or twist limits.
|
||||
|
||||
<Alert severity="info">
|
||||
When `Class.BallSocketConstraint.LimitsEnabled|LimitsEnabled` is enabled, orientation of a ball socket's attachments affects how it rotates. To ensure rotation occurs around the desired axis, each attachment's `Class.Attachment.Axis|Axis`, visualized by the yellow arrow, should point in the same direction.
|
||||
</Alert>
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
title: Cylindrical
|
||||
description: CylindricalConstraint allows its attachments to slide along one axis and rotate about another axis, with optional assigned angular and/or linear power.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mechanical constraints, including `Class.CylindricalConstraint`, see [Mechanical constraints](../../physics/mechanical-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.CylindricalConstraint` allows its attachments to slide along one axis and rotate about another axis. This constraint, along with a
|
||||
[SpringConstraint](../../physics/constraints/spring.md), is ideal for building vehicle suspensions where the wheel shock can slide up and down while the wheel itself spins. This constraint can also be powered in both an [angular](#angular-power) and [linear](#linear-power) manner.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/Cylindrical-Demo.mp4" width="90%" alt="Demo video of CylindricalConstraint"></video>
|
||||
|
||||
<Alert severity="info">
|
||||
Orientation of the attachments affects how the cylindrical aspect will rotate. To ensure rotation occurs around the desired axis, each attachment's `Class.Attachment.Axis|Axis` and `Class.Attachment.SecondaryAxis|SecondaryAxis`, visualized by the yellow and orange arrows, should point in the same direction.
|
||||
</Alert>
|
||||
|
||||
## Angular power
|
||||
|
||||
If a cylindrical's `Class.CylindricalConstraint.AngularActuatorType|AngularActuatorType` is set to `Enum.ActuatorType|Motor`, it attempts to rotate the attachments with the goal of reaching its `Class.CylindricalConstraint.AngularVelocity|AngularVelocity`. You can further control this rotation through both `Class.CylindricalConstraint.MotorMaxAngularAcceleration|MotorMaxAngularAcceleration` and `Class.CylindricalConstraint.MotorMaxTorque|MotorMaxTorque`.
|
||||
|
||||
If a cylindrical's `Class.CylindricalConstraint.AngularActuatorType|AngularActuatorType` is set to `Enum.ActuatorType|Servo`, it attempts to rotate to an angle specified by `Class.CylindricalConstraint.TargetAngle|TargetAngle`. This rotation is controlled by `Class.CylindricalConstraint.AngularSpeed|AngularSpeed`, `Class.CylindricalConstraint.AngularResponsiveness|AngularResponsiveness`, and `Class.CylindricalConstraint.ServoMaxTorque|ServoMaxTorque`.
|
||||
|
||||
## Linear power
|
||||
|
||||
If a cylindrical's `Class.CylindricalConstraint|ActuatorType` is set to `Enum.ActuatorType|Motor`, it attempts to translate the attachments with the goal of reaching `Class.CylindricalConstraint|Velocity`. You can further control this translation through both `Class.CylindricalConstraint|MotorMaxAcceleration` and `Class.CylindricalConstraint|MotorMaxForce`.
|
||||
|
||||
If a cylindrical's `Class.CylindricalConstraint|ActuatorType` is set to `Enum.ActuatorType|Servo`, it attempts to translate the attachments to a set separation specified by `Class.CylindricalConstraint|TargetPosition`. This translation is controlled by `Class.CylindricalConstraint|Speed`, `Class.CylindricalConstraint|LinearResponsiveness`, and `Class.CylindricalConstraint|ServoMaxForce`.
|
||||
|
||||
## Limits
|
||||
|
||||
You can set limits to restrict both the **sliding range** and **rotation** of a cylindrical constraint.
|
||||
|
||||
Enabling the `Class.CylindricalConstraint|LimitsEnabled` property exposes the `Class.CylindricalConstraint|LowerLimit` and `Class.CylindricalConstraint|UpperLimit` values, as well as `Class.CylindricalConstraint|Restitution` which defines the elasticity of the attachments when they reach either limit.
|
||||
|
||||
Enabling the `Class.CylindricalConstraint.AngularLimitsEnabled|AngularLimitsEnabled` property exposes the `Class.CylindricalConstraint.LowerAngle|LowerAngle` and `Class.CylindricalConstraint.UpperAngle|UpperAngle` limits, as well as `Class.CylindricalConstraint.AngularRestitution|AngularRestitution` which defines the elasticity of the attachments when they reach either limit.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Cylindrical-Limits-Linear.mp4" alt="Video showing effect of LimitsEnabled set to true"></video>
|
||||
<figcaption>LimitsEnabled = **true**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Cylindrical-Limits-Angular.mp4" alt="Video showing effect of AngularLimitsEnabled set to true"></video>
|
||||
<figcaption>AngularLimitsEnabled = **true**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Inclination angle
|
||||
|
||||
`Class.CylindricalConstraint.InclinationAngle|InclinationAngle` defines the direction of the rotation axis as an angle from the **X** axis in the **X**/**Y** plane of `Class.Constraint.Attachment0|Attachment0`, from -180 to 180. This lets you tilt the rotating element without changing the sliding axis.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Cylindrical-InclinationAngle-90.mp4" alt="Video showing InclinationAngle set to 90"></video>
|
||||
<figcaption>InclinationAngle = **90**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Cylindrical-InclinationAngle-30.mp4" alt="Video showing InclinationAngle set to 30"></video>
|
||||
<figcaption>InclinationAngle = **30**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
40
.cursor/rules/roblox/en-us/physics/constraints/hinge.md
Normal file
40
.cursor/rules/roblox/en-us/physics/constraints/hinge.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
title: Hinge
|
||||
description: HingeConstraint allows its two attachments to rotate about one axis, with optional assigned power for motor or servo behavior.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mechanical constraints, including `Class.HingeConstraint`, see [Mechanical constraints](../../physics/mechanical-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.HingeConstraint`
|
||||
allows its two attachments to rotate about one axis, forcing them into
|
||||
the same position and **X** axis alignment. This constraint can also be
|
||||
powered to behave like a [motor](#angular-power) or [servo](#angular-power), and you can set limits to restrict the hinge's rotational range.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/Hinge-Demo.mp4" width="90%" alt="Demo video of HingeConstraint"></video>
|
||||
|
||||
<Alert severity="info">
|
||||
Orientation of a hinge's attachments affects how it rotates. To ensure rotation occurs around the desired axis, each attachment's `Class.Attachment.Axis|Axis`, visualized by the yellow arrow, should point in the same direction.
|
||||
</Alert>
|
||||
|
||||
### Angular power
|
||||
|
||||
If a hinge's `Class.HingeConstraint.ActuatorType|ActuatorType` is set to `Enum.ActuatorType|Motor`, it attempts to rotate the attachments with the goal of reaching its `Class.HingeConstraint.AngularVelocity|AngularVelocity`. You can further control this rotation through both `Class.HingeConstraint.MotorMaxAcceleration|MotorMaxAcceleration` and `Class.HingeConstraint.MotorMaxTorque|MotorMaxTorque`.
|
||||
|
||||
If a hinge's `Class.HingeConstraint.ActuatorType|ActuatorType` is set to `Enum.ActuatorType|Servo`, it attempts to rotate to an angle specified by `Class.HingeConstraint.TargetAngle|TargetAngle`. This rotation is controlled by both `Class.HingeConstraint.AngularSpeed|AngularSpeed` and `Class.HingeConstraint.ServoMaxTorque|ServoMaxTorque`.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Hinge-ActuatorType-Motor.mp4" alt="Video showing angular power configured for motor behavior"></video>
|
||||
<figcaption>ActuatorType = **Motor**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Hinge-ActuatorType-Servo.mp4" alt="Video showing angular power configured for servo behavior"></video>
|
||||
<figcaption>ActuatorType = **Servo**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
### Limits
|
||||
|
||||
You can set limits to restrict the rotation of a hinge, useful for mechanisms like doors which should only swing open or closed within a set range. Enabling the `Class.HingeConstraint.LimitsEnabled|LimitsEnabled` property exposes the `Class.HingeConstraint.LowerAngle|LowerAngle` and `Class.HingeConstraint.UpperAngle|UpperAngle` limits, as well as `Class.HingeConstraint.Restitution|Restitution` which defines the elasticity of the attachments when they reach either limit.
|
||||
57
.cursor/rules/roblox/en-us/physics/constraints/line-force.md
Normal file
57
.cursor/rules/roblox/en-us/physics/constraints/line-force.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
title: LineForce
|
||||
description: The LineForce constraint applies force along the theoretical line connecting its two attachments.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mover constraints, including `Class.LineForce`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
The `Class.LineForce` constraint applies force along the theoretical line connecting its two `Class.Attachment|Attachments`. As the end points (attachments) move, the direction of force will change accordingly.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/LineForce-Demo.mp4" width="90%" alt="Demo video of LineForce constraint"></video>
|
||||
|
||||
## Force location
|
||||
|
||||
By default, force is applied to either parent at its attachment location. If desired, force can be focused at each parent's center of mass by toggling on `Class.LineForce.ApplyAtCenterOfMass|ApplyAtCenterOfMass`.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/LineForce-ApplyAtCenterOfMass-False.mp4" alt="Video showing ApplyAtCenterOfMass set to false"></video>
|
||||
<figcaption>ApplyAtCenterOfMass = **false**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/LineForce-ApplyAtCenterOfMass-True.mp4" alt="Video showing ApplyAtCenterOfMass set to true"></video>
|
||||
<figcaption>ApplyAtCenterOfMass = **true**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Inverse square law
|
||||
|
||||
When `Class.LineForce.InverseSquareLaw|InverseSquareLaw` is true, the force magnitude is multiplied by the inverse square of the distance, meaning the force will increase exponentially as the two attachments get closer together, like magnets. When using this setting, it's recommended that you set a `Class.LineForce.MaxForce|MaxForce` threshold to prevent infinite force if the attachments align precisely.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/LineForce-InverseSquareLaw-False.mp4" alt="Video showing InverseSquareLaw set to false"></video>
|
||||
<figcaption>InverseSquareLaw = **false**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/LineForce-InverseSquareLaw-True.mp4" alt="Video showing InverseSquareLaw set to true"></video>
|
||||
<figcaption>InverseSquareLaw = **true**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Reactionary force
|
||||
|
||||
By default, the constraint only applies force to `Class.Constraint.Attachment0|Attachment0`, while `Class.Constraint.Attachment1|Attachment1` remains unaffected. However, force can be applied to both attachments in **equal and opposite directions** by enabling `Class.LineForce.ReactionForceEnabled|ReactionForceEnabled`.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/LineForce-ReactionForceEnabled-False.mp4" alt="Video showing ReactionForceEnabled set to false"></video>
|
||||
<figcaption>ReactionForceEnabled = **false**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/LineForce-ReactionForceEnabled-True.mp4" alt="Video showing ReactionForceEnabled set to true"></video>
|
||||
<figcaption>ReactionForceEnabled = **true**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
title: LinearVelocity
|
||||
description: The LinearVelocity constraint applies force on an assembly to maintain a constant velocity along a 3D vector, line, or 2D plane.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mover constraints, including `Class.LinearVelocity`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.LinearVelocity` constraint applies force on an assembly to maintain a constant velocity. It can be set to apply force along a `Datatype.Vector3`, line, or 2D plane.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/LinearVelocity-Demo.mp4" width="90%" alt="Demo video of LinearVelocity constraint"></video>
|
||||
|
||||
<Alert severity="warning">
|
||||
The `Class.LinearVelocity` constraint applies a force that attempts to maintain a **constant** linear velocity. If you want to control the amount of force applied, use a [VectorForce](../../physics/constraints/vector-force.md) constraint. Alternatively, if you only need **initial** linear velocity, set the `Class.BasePart.AssemblyLinearVelocity|AssemblyLinearVelocity` property directly on the assembly.
|
||||
</Alert>
|
||||
|
||||
## Relativity
|
||||
|
||||
Application of velocity can be controlled through the constraint's `Class.LinearVelocity.RelativeTo|RelativeTo` property. If set to `Enum.ActuatorRelativeTo|World`, force will be applied in world coordinates, independent of the parent or attachment orientations. If set to `Enum.ActuatorRelativeTo|Attachment0` or `Enum.ActuatorRelativeTo|Attachment1`, force will be applied relative to `Class.Constraint.Attachment0|Attachment0` or `Class.Constraint.Attachment1|Attachment1` respectively.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/LinearVelocity-RelativeTo-World.mp4" alt="Video showing relative behavior set to world space"></video>
|
||||
<figcaption>RelativeTo = **World**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/LinearVelocity-RelativeTo-Attachment0.mp4" alt="Video showing relative behavior set to Attachment0"></video>
|
||||
<figcaption>RelativeTo = **Attachment0**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: NoCollision
|
||||
description: NoCollisionConstraint prevents collisions between two specific parts, but those parts may still register collisions with the rest of the world.
|
||||
---
|
||||
|
||||
The `Class.NoCollisionConstraint` prevents collisions between two specific parts, but those parts may still register collisions with the rest of the world. Compared to [collision groups](../../workspace/collisions.md#collision-groups), it provides a direct way to disable specific collisions, such as the wheel of a car scraping against the car's body.
|
||||
23
.cursor/rules/roblox/en-us/physics/constraints/plane.md
Normal file
23
.cursor/rules/roblox/en-us/physics/constraints/plane.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
title: Plane
|
||||
description: PlaneConstraint moves two attachments into a position/orientation along a plane, and both attachments remain free to translate and rotate unless otherwise constrained.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mechanical constraints, including `Class.PlaneConstraint`, see [Mechanical constraints](../../physics/mechanical-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.PlaneConstraint` moves its `Class.Constraint.Attachment0|Attachment0` and `Class.Constraint.Attachment1|Attachment1` into a position/orientation along a plane whose normal vector is the primary axis of `Class.Constraint.Attachment0|Attachment0`. Both parent assemblies remain free to translate and rotate unless otherwise constrained.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/Plane-Demo.mp4" width="90%" alt="Demo video of PlaneConstraint"></video>
|
||||
|
||||
Compare the following examples for how the orientation of `Class.Constraint.Attachment0|Attachment0` defines the plane, while the orientation of `Class.Constraint.Attachment1|Attachment1` has no bearing.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Orientation = (0, 0, 90)">
|
||||
<img src="../../assets/physics/constraints/Plane-Attachment0-1.jpg" width="672" height="378" alt="Attachment0 oriented to (0, 0, 90)" />
|
||||
</TabItem>
|
||||
<TabItem label="Orientation = (-45, 0, 90)">
|
||||
<img src="../../assets/physics/constraints/Plane-Attachment0-2.jpg" width="672" height="378" alt="Attachment0 oriented to (-45, 0, 90)" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
37
.cursor/rules/roblox/en-us/physics/constraints/prismatic.md
Normal file
37
.cursor/rules/roblox/en-us/physics/constraints/prismatic.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
title: Prismatic
|
||||
description: PrismaticConstraint allows two attachments to slide along one axis but not rotate, with optional assigned power for mechanisms like sliding doors and elevator platforms.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mechanical constraints, including `Class.PrismaticConstraint`, see [Mechanical constraints](../../physics/mechanical-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.PrismaticConstraint` creates a rigid joint between two attachments, allowing them to slide along one axis but not rotate. The constraint can also be [powered](#linear-power) for mechanisms like sliding doors and elevator platforms.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/Prismatic-Demo.mp4" width="90%" alt="Demo video of PrismaticConstraint"></video>
|
||||
|
||||
<Alert severity="info">
|
||||
Orientation of a prismatic's attachments affects how it will move. To ensure movement occurs along the desired axis, each attachment's `Class.Attachment.Axis|Axis`, visualized by the yellow arrow, should point in the same direction.
|
||||
</Alert>
|
||||
|
||||
## Linear power
|
||||
|
||||
If a prismatic's `Class.PrismaticConstraint|ActuatorType` is set to `Enum.ActuatorType|Motor`, it attempts to translate the attachments with the goal of reaching `Class.PrismaticConstraint|Velocity`. You can further control this translation through both `Class.PrismaticConstraint|MotorMaxAcceleration` and `Class.PrismaticConstraint|MotorMaxForce`.
|
||||
|
||||
If a prismatic's `Class.PrismaticConstraint|ActuatorType` is set to `Enum.ActuatorType|Servo`, it attempts to translate the attachments to a set separation specified by `Class.PrismaticConstraint|TargetPosition`. This translation is controlled by `Class.PrismaticConstraint|Speed`, `Class.PrismaticConstraint|LinearResponsiveness`, and `Class.PrismaticConstraint|ServoMaxForce`.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Prismatic-ActuatorType-Motor.mp4" alt="Video showing linear power configured for motor behavior"></video>
|
||||
<figcaption>ActuatorType = **Motor**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Prismatic-ActuatorType-Servo.mp4" alt="Video showing linear power configured for servo behavior"></video>
|
||||
<figcaption>ActuatorType = **Servo**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Limits
|
||||
|
||||
You can set limits to restrict the sliding range a prismatic. Enabling the `Class.PrismaticConstraint|LimitsEnabled` property exposes the `Class.PrismaticConstraint|LowerLimit` and `Class.PrismaticConstraint|UpperLimit` values, as well as `Class.PrismaticConstraint|Restitution` which defines the elasticity of the attachments when they reach either limit.
|
||||
17
.cursor/rules/roblox/en-us/physics/constraints/rigid.md
Normal file
17
.cursor/rules/roblox/en-us/physics/constraints/rigid.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
title: Rigid
|
||||
description: RigidConstraint connects two attachments with zero offset.
|
||||
---
|
||||
|
||||
A `Class.RigidConstraint` connects two `Class.Attachment|Attachments` or `Class.Bone|Bones` and ensures they stay in the same relative position/orientation to each other. This flexibility gives it additional functionality beyond `Class.WeldConstraint`, such as attaching accessories to `Class.Attachment|Attachments` on a character rig.
|
||||
|
||||
<Alert severity="info">
|
||||
To attach two `Class.BasePart|BaseParts` together, versus two `Class.Attachment|Attachments` or `Class.Bone|Bones`, see [WeldConstraint](../../physics/constraints/weld.md).
|
||||
</Alert>
|
||||
|
||||
When creating a `Class.RigidConstraint` using Studio's [Constraint](../mechanical-constraints.md#create-constraints) button, the tool behaves differently depending on whether you click on existing `Class.BasePart|BaseParts`, `Class.Attachment|Attachments`, or `Class.Bone|Bones` after the tool is activated:
|
||||
|
||||
- Clicking on an existing `Class.BasePart` creates a new `Class.Attachment` upon it as the intended `Class.RigidConstraint.Attachment0` or `Class.RigidConstraint.Attachment1`.
|
||||
- Clicking on an existing `Class.Attachment` or `Class.Bone` uses that instance as the intended `Class.RigidConstraint.Attachment0` or `Class.RigidConstraint.Attachment1`.
|
||||
|
||||
Following the second valid click, a new `Class.RigidConstraint` is created to connect the two new attachments. If either the first or second click is **not** made on a `Class.BasePart`, `Class.Attachment`, or `Class.Bone`, the workflow is canceled and no constraint is created.
|
||||
16
.cursor/rules/roblox/en-us/physics/constraints/rod.md
Normal file
16
.cursor/rules/roblox/en-us/physics/constraints/rod.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
title: Rod
|
||||
description: RodConstraint keeps two attachments separated by a defined length, with optional limits on rotational tilt.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mechanical constraints, including `Class.RodConstraint`, see [Mechanical constraints](../../physics/mechanical-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.RodConstraint` keeps two attachments separated by its defined `Class.RodConstraint.Length|Length`. By default, both attachments can rotate freely, although you can enable limits to restrict rotational tilt.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/Rod-Demo.mp4" width="90%" alt="Demo video of RodConstraint"></video>
|
||||
|
||||
## Limits
|
||||
|
||||
You can limit rotation of the attachments within a cone, independently of each other, by enabling the `Class.RodConstraint.LimitsEnabled|LimitsEnabled` property and setting `Class.RodConstraint.LimitAngle0|LimitAngle0` and `Class.RodConstraint.LimitAngle1|LimitAngle1` respectively.
|
||||
22
.cursor/rules/roblox/en-us/physics/constraints/rope.md
Normal file
22
.cursor/rules/roblox/en-us/physics/constraints/rope.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
title: Rope
|
||||
description: RopeConstraint prevents two attachments from separating further than a defined length, with optional behavior as an extending or contracting winch.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mechanical constraints, including `Class.RopeConstraint`, see [Mechanical constraints](../../physics/mechanical-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.RopeConstraint` prevents two attachments from separating further than a defined `Class.RopeConstraint.Length|Length`. The attachments can move closer together than this length and both can freely rotate. `Class.RopeConstraint.Restitution|Restitution` defines the elasticity of the attachments when they reach the separation limit specified by `Class.RopeConstraint.Length|Length`.
|
||||
|
||||
This constraint can also be powered to behave as a [motorized winch](#winch).
|
||||
|
||||
<video controls src="../../assets/physics/constraints/Rope-Demo.mp4" width="90%" alt="Demo video of RopeConstraint"></video>
|
||||
|
||||
## Winch
|
||||
|
||||
If a rope's `Class.RopeConstraint.WinchEnabled|WinchEnabled` property is enabled, it attempts to translate the attachments to a set separation specified by `Class.RopeConstraint.WinchTarget|WinchTarget`, effectively the target length of the rope in studs. This translation is controlled by `Class.RopeConstraint.WinchSpeed|WinchSpeed`, `Class.RopeConstraint.WinchResponsiveness|WinchResponsiveness`, and `Class.RopeConstraint.WinchForce|WinchForce`.
|
||||
|
||||
<Alert severity="info">
|
||||
`Class.RopeConstraint.WinchSpeed|WinchSpeed` must be a **positive** value, used to either contract or extend the rope length to `Class.RopeConstraint.WinchTarget|WinchTarget`. Setting a negative speed will revert to 0, not reverse the winch servo direction.
|
||||
</Alert>
|
||||
39
.cursor/rules/roblox/en-us/physics/constraints/spring.md
Normal file
39
.cursor/rules/roblox/en-us/physics/constraints/spring.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
title: Spring
|
||||
description: SpringConstraint applies a force on its attachments based on spring and damper behavior, with an optional minimum/maximum length.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mechanical constraints, including `Class.SpringConstraint`, see [Mechanical constraints](../../physics/mechanical-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.SpringConstraint` applies a force on its attachments based on spring and damper behavior. You can customize a spring's [damping](#damping) and [stiffness](#stiffness), as well as set minimum and maximum [limits](#limits) on the spring's length.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/Spring-Demo.mp4" width="90%" alt="Demo video of SpringConstraint"></video>
|
||||
|
||||
## Free length
|
||||
|
||||
`Class.SpringConstraint.FreeLength|FreeLength` defines the natural resting length of the spring. If the attachments are further apart than the free length, they are forced together; if the attachments are closer together than the free length, they are forced apart.
|
||||
|
||||
## Damping
|
||||
|
||||
The `Class.SpringConstraint.Damping|Damping` value controls how fast the spring's oscillation dies down. A value of 0 allows the spring to oscillate endlessly, while higher values bring the spring to a rest more quickly.
|
||||
|
||||
## Stiffness
|
||||
|
||||
`Class.SpringConstraint.Stiffness|Stiffness` sets the strength of the spring. Higher values create a spring that responds with more force when its attachments are closer together or further apart than `Class.SpringConstraint.FreeLength|FreeLength`.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Spring-Stiffness-25.mp4" alt="Video showing Stiffness set to 25"></video>
|
||||
<figcaption>Stiffness = **25**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Spring-Stiffness-500.mp4" alt="Video showing Stiffness set to 500"></video>
|
||||
<figcaption>Stiffness = **500**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Limits
|
||||
|
||||
Enabling the `Class.SpringConstraint.LimitsEnabled|LimitsEnabled` property exposes the `Class.SpringConstraint.MinLength|MinLength` and `Class.SpringConstraint.MaxLength|MaxLength` values for setting the minimum and maximum length of the spring. If the spring's attachments reach these limits, they stop moving apart from one another without restitution.
|
||||
35
.cursor/rules/roblox/en-us/physics/constraints/torque.md
Normal file
35
.cursor/rules/roblox/en-us/physics/constraints/torque.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
title: Torque
|
||||
description: The Torque constraint applies constant torque on an assembly from its center of mass.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mover constraints, including `Class.Torque`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.Torque` constraint applies constant torque on an assembly from its center of mass.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/Torque-Demo.mp4" width="90%" alt="Demo video of Torque constraint"></video>
|
||||
|
||||
<Alert severity="warning">
|
||||
Because the `Class.Torque` constraint applies **constant** torque and angular acceleration, very high speeds may result if no other forces are involved. If you want to maintain a more steady velocity over time, use an [AngularVelocity](../../physics/constraints/angular-velocity.md) constraint. Alternatively, if you only need **initial** velocity, set the `Class.BasePart.AssemblyAngularVelocity|AssemblyAngularVelocity` property directly on the assembly.
|
||||
</Alert>
|
||||
|
||||
## Relativity
|
||||
|
||||
By default, torque is applied relative to `Class.Constraint.Attachment0|Attachment0`. If the parent assembly rotates, the torque will change direction to match the adjusted orientation of the attachment.
|
||||
|
||||
If `Class.Torque.RelativeTo|RelativeTo` is set to **World**, torque will be applied in world coordinates, independent of the parent or attachment orientations.
|
||||
|
||||
If `Class.Torque.RelativeTo|RelativeTo` is set to **Attachment1**, torque will be applied relative to `Class.Constraint.Attachment1|Attachment1` and, if the attachment rotates, change to match its orientation.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Torque-RelativeTo-Attachment0.mp4" alt="Video showing RelativeTo set to Attachment0"></video>
|
||||
<figcaption>RelativeTo = **Attachment0**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/Torque-RelativeTo-World.mp4" alt="Video showing RelativeTo set to World"></video>
|
||||
<figcaption>RelativeTo = **World**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
title: TorsionSpring
|
||||
description: TorsionSpringConstraint applies torque based on a relative angle and relative angular velocity, in an attempt to bring two axes from two parts together.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mechanical constraints, including `Class.TorsionSpringConstraint`, see [Mechanical constraints](../../physics/mechanical-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.TorsionSpringConstraint` applies torque based on a relative angle and relative angular velocity. It attempts to bring two axes from two parts together and is useful for [hinged](../../physics/constraints/hinge.md) swinging doors with a spring-back effect.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/TorsionSpring-Demo.mp4" width="90%" alt="Demo video of TorsionSpringConstraint"></video>
|
||||
|
||||
<Alert severity="info">
|
||||
Correct orientation of a torsion spring's attachments is important. The constraint will attempt to bring the `Class.Attachment.SecondaryAxis|SecondaryAxis` of each attachment, visualized by the orange arrows, into alignment. When building mechanisms like swinging doors, ensure that the secondary axes are **perpendicular** to the intended axis of rotation.
|
||||
</Alert>
|
||||
|
||||
## Damping
|
||||
|
||||
The `Class.TorsionSpringConstraint.Damping|Damping` value controls how fast the spring's oscillation dies down. A value of 0 allows the spring to oscillate endlessly, while higher values bring the spring to a rest more quickly.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/TorsionSpring-Damping-0.mp4" alt="Video showing Damping set to 0"></video>
|
||||
<figcaption>Damping = **0**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/TorsionSpring-Damping-50.mp4" alt="Video showing Damping set to 50"></video>
|
||||
<figcaption>Damping = **50**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Stiffness
|
||||
|
||||
`Class.TorsionSpringConstraint.Stiffness|Stiffness` sets the torsional strength of the spring. Higher values create a spring that responds with more force.
|
||||
|
||||
## Limits
|
||||
|
||||
Enabling the `Class.TorsionSpringConstraint.LimitsEnabled|LimitsEnabled` property exposes the `Class.TorsionSpringConstraint.MaxAngle|MaxAngle` value to restrict the spring's range within a cone; it also exposes the `Class.TorsionSpringConstraint.Restitution|Restitution` value which defines the elasticity of the attachments when they reach their limit.
|
||||
29
.cursor/rules/roblox/en-us/physics/constraints/universal.md
Normal file
29
.cursor/rules/roblox/en-us/physics/constraints/universal.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
title: Universal
|
||||
description: UniversalConstraint ensures two axes on two assemblies remain perpendicular, useful for applications such as vehicle power transmission to rear drive shafts, robotics, and more.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mechanical constraints, including `Class.UniversalConstraint`, see [Mechanical constraints](../../physics/mechanical-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
A `Class.UniversalConstraint` ensures two axes on two assemblies remain perpendicular. Example applications include vehicle power transmission to the rear drive shafts, robotics, and more.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/Universal-Demo.mp4" width="90%" alt="Demo video of UniversalConstraint"></video>
|
||||
|
||||
## Orientations
|
||||
|
||||
Orientation of a universal's two attachments affects how it will move. To ensure it behaves correctly, the `Class.Attachment.SecondaryAxis|SecondaryAxis` of the attachments, visualized by the orange arrows, should be **perpendicular** to each other. Note that a green L-shaped indicator appears when the axes are properly oriented.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Axes Perpendicular">
|
||||
<img src="../../assets/physics/constraints/Universal-Attachments-Correct.jpg" width="672" height="378" alt="Secondary axes perpendicular for correct behavior" />
|
||||
</TabItem>
|
||||
<TabItem label="Axes Misoriented">
|
||||
<img src="../../assets/physics/constraints/Universal-Attachments-Incorrect.jpg" width="672" height="378" alt="Secondary axes misoriented" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Limits
|
||||
|
||||
Enabling the `Class.UniversalConstraint.LimitsEnabled|LimitsEnabled` property exposes the `Class.UniversalConstraint.MaxAngle|MaxAngle` limit to restrict tilt within a cone, as well as `Class.UniversalConstraint.Restitution|Restitution` which defines the elasticity of the attachments when they reach the limit.
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
title: VectorForce
|
||||
description: The VectorForce constraint applies constant linear force on an assembly.
|
||||
---
|
||||
|
||||
<Alert severity="info">
|
||||
For an overview on creating, visualizing, and simulating mover constraints, including `Class.VectorForce`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
|
||||
</Alert>
|
||||
|
||||
The `Class.VectorForce` constraint applies constant linear force on an assembly. The direction and strength of the force is determined by a `Datatype.Vector3` and can be relative to an attachment on the part, another attachment, or the world coordinate system.
|
||||
|
||||
<video controls src="../../assets/physics/constraints/VectorForce-Demo.mp4" width="90%" alt="Demo video of VectorForce constraint"></video>
|
||||
|
||||
<Alert severity="warning">
|
||||
Because the `Class.VectorForce` constraint applies **constant** force and acceleration, very high speeds may result if no other forces are involved. If you want to maintain a more steady velocity over time, use a [LinearVelocity](../../physics/constraints/linear-velocity.md) constraint. Alternatively, if you only need **initial** velocity, set the `Class.BasePart.AssemblyLinearVelocity|AssemblyLinearVelocity` property directly on the assembly.
|
||||
</Alert>
|
||||
|
||||
## Force location
|
||||
|
||||
By default, force is applied to the assembly at the location of `Class.Constraint.Attachment0|Attachment0`. Thus, if its center of mass is not aligned with the direction/point of force, torque will be applied as well. If desired, force can be focused at the center of mass by toggling on `Class.VectorForce.ApplyAtCenterOfMass|ApplyAtCenterOfMass`.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/VectorForce-ApplyAtCenterOfMass-False.mp4" alt="Video showing ApplyAtCenterOfMass set to false"></video>
|
||||
<figcaption>ApplyAtCenterOfMass = **false**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/VectorForce-ApplyAtCenterOfMass-True.mp4" alt="Video showing ApplyAtCenterOfMass set to true"></video>
|
||||
<figcaption>ApplyAtCenterOfMass = **true**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
## Relativity
|
||||
|
||||
By default, force is applied relative to `Class.Constraint.Attachment0|Attachment0`. If the parent assembly rotates, the force will change direction to match the adjusted orientation of the attachment; visualize this behavior in how the thruster of a rocket pushes it forward, regardless of the rocket's rotation.
|
||||
|
||||
If `Class.VectorForce.RelativeTo|RelativeTo` is set to **World**, force will be applied in world coordinates, independent of the parent or attachment orientations; visualize this behavior as a directional force like the wind blowing against an object.
|
||||
|
||||
If `Class.VectorForce.RelativeTo|RelativeTo` is set to **Attachment1**, force will be applied relative to `Class.Constraint.Attachment1|Attachment1` and, if the attachment rotates, the force will change to match its orientation.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/VectorForce-RelativeTo-Attachment0.mp4" alt="Video showing RelativeTo set to Attachment0"></video>
|
||||
<figcaption>RelativeTo = **Attachment0**</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<video controls src="../../assets/physics/constraints/VectorForce-RelativeTo-World.mp4" alt="Video showing RelativeTo set to World"></video>
|
||||
<figcaption>RelativeTo = **World**</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
36
.cursor/rules/roblox/en-us/physics/constraints/weld.md
Normal file
36
.cursor/rules/roblox/en-us/physics/constraints/weld.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
title: Weld
|
||||
description: WeldConstraint attaches two BaseParts together and ensures they stay in the same relative position and orientation to each other.
|
||||
---
|
||||
|
||||
A `Class.WeldConstraint` connects two `Class.BasePart|BaseParts` and ensures they stay in the same relative position and orientation to each other. Even if the two parts are not touching, you can weld them together.
|
||||
|
||||
<Alert severity="info">
|
||||
To attach two `Class.Attachment|Attachments` or `Class.Bone|Bones`, versus two `Class.BasePart|BaseParts`, see [RigidConstraint](../../physics/constraints/rigid.md).
|
||||
</Alert>
|
||||
|
||||
Unique to `Class.WeldConstraint` are slight behavioral differences in how Studio handles creation and repositioning of welded parts.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Weld Creation">
|
||||
When creating a `Class.WeldConstraint` using Studio's [Constraint](../mechanical-constraints.md#create-constraints) button, the tool behaves differently depending on how many `Class.BasePart|BaseParts` are selected when the tool is activated:
|
||||
|
||||
- If no `Class.BasePart|BaseParts` are selected, the next two `Class.BasePart|BaseParts` clicked will be connected by a new `Class.WeldConstraint`. If the same `Class.BasePart` is clicked twice, no constraint will be created.
|
||||
- If one `Class.BasePart` is already selected, the next `Class.BasePart` clicked will be connected to the selected one with a new `Class.WeldConstraint`.
|
||||
- If multiple `Class.BasePart|BaseParts` are selected, those which are touching or overlapping will be automatically welded together by new `Class.WeldConstraint|WeldConstraints`.
|
||||
</TabItem>
|
||||
<TabItem label="Repositioning Welded Parts">
|
||||
Roblox handles moving a welded part differently depending on whether the part
|
||||
was moved through its `Class.BasePart.Position|Position` or through its
|
||||
`Datatype.CFrame`.
|
||||
|
||||
- If a welded part's `Class.BasePart.Position|Position` is updated, that part
|
||||
will move but none of the connected parts will move with it. The weld will
|
||||
recalculate the offset from the other parts based on the moved part's new
|
||||
position.
|
||||
|
||||
- If a welded part's `Datatype.CFrame` is updated, that part will move **and**
|
||||
all of the connected parts will also move, ensuring they maintain the same
|
||||
offset as when the weld was created.
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
61
.cursor/rules/roblox/en-us/physics/index.md
Normal file
61
.cursor/rules/roblox/en-us/physics/index.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
title: Physics
|
||||
description: Overview of Roblox's rigid body physics engine, assemblies, and constraints.
|
||||
---
|
||||
|
||||
Roblox uses a rigid body physics engine. Parts are subject to physical forces as long as they are not `Class.BasePart.Anchored|anchored`. You can create physical [assemblies](#assemblies) using attachments and constraints, and you can detect and control [collisions](#collisions) between objects using events and collision filtering.
|
||||
|
||||
## Assemblies
|
||||
|
||||
An [assembly](../physics/assemblies.md) is one or more `Class.BasePart|BaseParts` connected by rigid constraints or motors (animated rigid joints). Assemblies can be set to an initial linear or angular velocity, or their behavior can be affected through [constraints](#constraints).
|
||||
|
||||
<Grid container spacing={0}>
|
||||
<Grid item XSmall={6} XLarge={3}>
|
||||
<img src="../assets/physics/assemblies/Assembly-Example-Block.png" alt="A light blue cube against a dark blue background that represents an assembly of 1 part." width="100%" />
|
||||
<figcaption>1 assembly; 1 part</figcaption>
|
||||
</Grid>
|
||||
<Grid item XSmall={6} XLarge={3}>
|
||||
<img src="../assets/physics/assemblies/Assembly-Example-Avatar.png" alt="A humanoid character model against a dark blue background that represents an assembly of 18 parts." width="100%" />
|
||||
<figcaption>1 assembly; 18 parts</figcaption>
|
||||
</Grid>
|
||||
<Grid item XSmall={12} XLarge={6}>
|
||||
<img src="../assets/physics/assemblies/Assembly-Example-Ship.png" alt="A pirate that represents an assemble of 179 parts." width="100%" />
|
||||
<figcaption>1 assembly; 179 parts</figcaption>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
## Constraints
|
||||
|
||||
Non-anchored assemblies react to force from gravity and collisions, but physical force can also be applied through **mechanical constraints** or **mover constraints**.
|
||||
|
||||
### Mechanical constraints
|
||||
|
||||
Mechanical constraints include familiar objects like hinges, springs, and ropes which can be used to build mechanisms. Each is covered in [Mechanical constraints](../physics/mechanical-constraints.md).
|
||||
|
||||
<video src="../assets/physics/constraints/Spring-Demo.mp4" controls width="100%"></video>
|
||||
|
||||
### Mover constraints
|
||||
|
||||
Mover constraints apply force or torque to move one or more assemblies. Each is outlined in [Mover constraints](../physics/mover-constraints.md).
|
||||
|
||||
<video src="../assets/physics/constraints/Torque-RelativeTo-Attachment0.mp4" controls width="100%"></video>
|
||||
|
||||
## Collisions
|
||||
|
||||
Collision events automatically occur when two `Class.BasePart|BaseParts` touch or stop touching in the 3D world. You can [detect](../workspace/collisions.md) these collisions through the `Class.BasePart.Touched|Touched` and `Class.BasePart.TouchEnded|TouchEnded` events which occur regardless of either part's `Class.BasePart.CanCollide|CanCollide` property value.
|
||||
|
||||
Through [collision filtering](../workspace/collisions.md#collision-filtering) techniques such as collision groups or part‑to‑part filtering, you can control which physical assemblies collide with others.
|
||||
|
||||
See [Collisions](../workspace/collisions.md) for more details on detecting and filtering collisions.
|
||||
|
||||
## Network ownership
|
||||
|
||||
In order to support complex physical mechanisms while also aiming for a smooth and responsive experience for players, the Roblox physics engine utilizes a **distributed physics** system in which computations are distributed between the server and all connected clients. Within this system, the engine assigns **network ownership** of physically simulated `Class.BasePart|BaseParts` to either a client or server to divide the work of calculating physics. See [Network ownership](../physics/network-ownership.md) for further details.
|
||||
|
||||
## Adaptive timestepping
|
||||
|
||||
The engine emphasizes best performance by automatically assigning assemblies to one of three simulation rates. For scenarios featuring complex mechanisms like tanks, you can improve stability by setting a fixed timestep. See [Adaptive timestepping](../physics/adaptive-timestepping.md) for more information.
|
||||
|
||||
## Sleep system
|
||||
|
||||
When an assembly is not moving or accelerating, the Roblox physics engine improves performance by automatically stops simulating the assembly. See [Sleep system](../physics/sleep-system.md) for a detailed description of the sleep system.
|
||||
227
.cursor/rules/roblox/en-us/physics/mechanical-constraints.md
Normal file
227
.cursor/rules/roblox/en-us/physics/mechanical-constraints.md
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
---
|
||||
title: Mechanical constraints
|
||||
description: Mechanical constraints behave as conceptual mechanical connections such as hinges, springs, and motors.
|
||||
---
|
||||
|
||||
import ConstraintVisualization from '../includes/studio/constraint-visualization.md'
|
||||
import ConstraintSimulation from '../includes/studio/constraint-simulation.md'
|
||||
|
||||
The physics engine includes the following `Class.Constraint|Constraints` that behave as conceptual mechanical connections, including hinges, springs, ropes, and more. In addition, various [mover constraints](../physics/mover-constraints.md) are available to exert directional or rotational force upon [assemblies](../physics/assemblies.md).
|
||||
|
||||
<Grid container spacing={4}>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/ball-socket.md" size="large" variant="contained" fullWidth>Ball Socket</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/BallInSocket-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[BallSocketConstraint](../physics/constraints/ball-socket.md) forces its two attachments into the same position and allows them to freely rotate about all three axes, with optional limits to restrict both tilt and twist</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/hinge.md" size="large" variant="contained" fullWidth>Hinge</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/Hinge-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[HingeConstraint](../physics/constraints/hinge.md) allows its two attachments to rotate about one axis, with optional assigned power for motor or servo behavior</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/prismatic.md" size="large" variant="contained" fullWidth>Prismatic</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/Prismatic-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[PrismaticConstraint](../physics/constraints/prismatic.md) allows two attachments to slide along one axis but not rotate, with optional assigned power for mechanisms like sliding doors and elevator platforms</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/cylindrical.md" size="large" variant="contained" fullWidth>Cylindrical</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/Cylindrical-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[CylindricalConstraint](../physics/constraints/cylindrical.md) allows its attachments to slide along one axis and rotate about another axis, with optional assigned angular and/or linear power</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/spring.md" size="large" variant="contained" fullWidth>Spring</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/Spring-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[SpringConstraint](../physics/constraints/spring.md) applies a force on its attachments based on spring and damper behavior, with an optional minimum/maximum length</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/torsion-spring.md" size="large" variant="contained" fullWidth>Torsion Spring</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/TorsionSpring-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[TorsionSpringConstraint](../physics/constraints/torsion-spring.md) applies torque based on a relative angle and relative angular velocity, in an attempt to bring two axes from two parts together</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/universal.md" size="large" variant="contained" fullWidth>Universal</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/Universal-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[UniversalConstraint](../physics/constraints/universal.md) ensures two axes on two assemblies remain perpendicular, useful for applications such as vehicle power transmission to rear drive shafts, robotics, and more</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/rope.md" size="large" variant="contained" fullWidth>Rope</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/Rope-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[RopeConstraint](../physics/constraints/rope.md) prevents two attachments from separating further than a defined length, with optional behavior as an extending or contracting winch</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/rod.md" size="large" variant="contained" fullWidth>Rod</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/Rod-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[RodConstraint](../physics/constraints/rod.md) keeps two attachments separated by a defined length, with optional limits on rotational tilt</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/plane.md" size="large" variant="contained" fullWidth>Plane</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/Plane-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[PlaneConstraint](../physics/constraints/plane.md) moves two attachments into a position/orientation along a plane, and both attachments remain free to translate and rotate unless otherwise constrained</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/weld.md" size="large" variant="contained" fullWidth>Weld</Button>
|
||||
<p></p>
|
||||
<figcaption>[WeldConstraint](../physics/constraints/weld.md) connects two `Class.BasePart|BaseParts` and ensures they stay in the same relative position and orientation to each other, even if they are not touching</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/rigid.md" size="large" variant="contained" fullWidth>Rigid</Button>
|
||||
<p></p>
|
||||
<figcaption>[RigidConstraint](../physics/constraints/rigid.md) connects two `Class.Attachment|Attachments` or `Class.Bone|Bones` and ensures they stay in the same relative position/orientation to each other, even if they are not touching</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/no-collision.md" size="large" variant="contained" fullWidth>No Collision</Button>
|
||||
<p></p>
|
||||
<figcaption>[NoCollisionConstraint](../physics/constraints/no-collision.md) prevents collisions between two specific parts, but those parts may still register collisions with the rest of the world</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
## Constraint visualization
|
||||
|
||||
<ConstraintVisualization components={props.components} />
|
||||
|
||||
## Create constraints
|
||||
|
||||
All mechanical constraints must connect one or two `Class.Attachment|Attachments` or `Class.Bone|Bones`, except for [WeldConstraint](../physics/constraints/weld.md) and [NoCollisionConstraint](../physics/constraints/no-collision.md). When connected to `Class.Bone|Bones`, the constraint will use their animated position and orientation.
|
||||
|
||||
To create a mechanical constraint, you can either insert one from the **Constraint** picker/button or through the [Explorer](../studio/explorer.md) window.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Constraint Picker">
|
||||
|
||||
1. In Studio's **Model** tab toolbar, click‑hold over the small corner arrow on a constraint button to open its picker menu, then select the desired constraint.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Constraint-Pickers.png" width="800" alt="Constraint pickers indicated in Studio's toolbar" />
|
||||
|
||||
2. In the 3D viewport, hover over any `Class.Part` or `Class.MeshPart` and click to add a new `Class.Attachment` to the part at the visualized point. Alternatively, hover over and click an existing `Class.Attachment` or `Class.Bone` to use it for the constraint.
|
||||
|
||||
3. Most mechanical constraints require a **secondary** attachment in their functionality, so the tool will typically prompt you to repeat the previous step on another `Class.Part`, `Class.MeshPart`, `Class.Attachment`, or `Class.Bone`.
|
||||
|
||||
<figure>
|
||||
<img src="../assets/physics/constraints/Creation-Diagram.jpg" width="600" alt="SpringConstraint connecting two attachments on separate blocks. One block is green and the other is blue." />
|
||||
<figcaption>Completed [SpringConstraint](../physics/constraints/spring.md) connecting two attachments</figcaption>
|
||||
</figure>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Explorer">
|
||||
<Alert severity="info">
|
||||
Note that [WeldConstraint](../physics/constraints/weld.md) and [NoCollisionConstraint](../physics/constraints/no-collision.md) do not utilize `Class.Attachment|Attachments` or `Class.Bone|Bones`, so their linking properties in the following steps are **Part0**/**Part1**, not **Attachment0**/**Attachment1**. Similarly, you'll need to select a `Class.Part` or `Class.MeshPart` to complete the link, not an `Class.Attachment` or `Class.Bone`.
|
||||
</Alert>
|
||||
|
||||
1. In the [Explorer](../studio/explorer.md) hierarchy, hover over the intended parent, click the **⊕** button, and insert the desired constraint from the dropdown menu, such as a [SpringConstraint](../physics/constraints/spring.md).
|
||||
|
||||
<img src="../assets/studio/explorer/SpringConstraint.png" width="320" alt="New SpringConstraint in Explorer hierarchy." />
|
||||
|
||||
1. With the new constraint selected, locate its currently empty **Attachment0** property in the [Properties](../studio/properties.md) window.
|
||||
|
||||
<img src="../assets/studio/properties/SpringConstraint-Attachment0-Unassigned.png" width="320" alt="Constraint's Attachment0 property highlighted in the Properties window." />
|
||||
|
||||
1. Link the **Attachment0** property to an `Class.Attachment` or `Class.Bone` in two consecutive steps:
|
||||
|
||||
1. In the [Properties](../studio/properties.md) window, click in the **Attachment0** row to reveal the selection cursor.
|
||||
|
||||
2. In the [Explorer](../studio/explorer.md) hierarchy, click on the target `Class.Attachment` or `Class.Bone`.
|
||||
|
||||
<Grid container spacing={3}>
|
||||
<Grid item>
|
||||
<img src="../assets/physics/constraints/SpringConstraint-Link-Attachment0-1.png" width="320" alt="Mouse pointer hovering over Attachment0 property in the Properties window." />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<img src="../assets/physics/constraints/SpringConstraint-Link-Attachment0-2.png" width="320" alt="Target attachment indicated in Explorer hierarchy." />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
1. Most mechanical constraints require a **secondary** `Class.Attachment` or `Class.Bone` in their functionality. If necessary, repeat the previous step on the **Attachment1** property in the [Properties](../studio/properties.md) window.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Physical simulation
|
||||
|
||||
<ConstraintSimulation components={props.components} />
|
||||
221
.cursor/rules/roblox/en-us/physics/mover-constraints.md
Normal file
221
.cursor/rules/roblox/en-us/physics/mover-constraints.md
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
---
|
||||
title: Mover constraints
|
||||
description: Mover constraints apply force or torque to move one or more assemblies.
|
||||
---
|
||||
|
||||
import ConstraintVisualization from '../includes/studio/constraint-visualization.md'
|
||||
import ConstraintSimulation from '../includes/studio/constraint-simulation.md'
|
||||
|
||||
The physics engine includes the following `Class.Constraint|Constraints` that apply force or torque to move one or more assemblies. In addition, various [mechanical constraints](../physics/mechanical-constraints.md) are available which behave as conceptual mechanical connections, including hinges, springs, ropes, and more.
|
||||
|
||||
<Grid container spacing={4}>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/linear-velocity.md" size="large" variant="contained" fullWidth>Linear Velocity</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/LinearVelocity-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[LinearVelocity](../physics/constraints/linear-velocity.md) applies force on an assembly to maintain a constant velocity along a 3D vector, line, or 2D plane</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/angular-velocity.md" size="large" variant="contained" fullWidth>Angular Velocity</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/AngularVelocity-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[AngularVelocity](../physics/constraints/angular-velocity.md) applies torque on an assembly to maintain a constant angular velocity</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/align-position.md" size="large" variant="contained" fullWidth>Align Position</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/AlignPosition-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[AlignPosition](../physics/constraints/align-position.md) applies force to move two attachments together, or to move one attachment to a goal position</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/align-orientation.md" size="large" variant="contained" fullWidth>Align Orientation</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/AlignOrientation-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[AlignOrientation](../physics/constraints/align-orientation.md) applies torque to align two attachments, or to align one attachment with a goal orientation</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/vector-force.md" size="large" variant="contained" fullWidth>Vector Force</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/VectorForce-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[VectorForce](../physics/constraints/vector-force.md) applies constant linear force on an assembly</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/torque.md" size="large" variant="contained" fullWidth>Torque</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/Torque-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[Torque](../physics/constraints/torque.md) applies constant torque on an assembly from its center of mass</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
<Grid item XSmall={12} Small={6} Medium={6} Large={6}>
|
||||
<Card variant="outlined" style={{height: '100%'}}>
|
||||
<CardContent>
|
||||
<Button href="../physics/constraints/line-force.md" size="large" variant="contained" fullWidth>Line Force</Button>
|
||||
<p></p>
|
||||
<CardMedia component="video" controls src="../assets/physics/constraints/LineForce-Demo.mp4" />
|
||||
<p></p>
|
||||
<figcaption>[LineForce](../physics/constraints/line-force.md) applies force along the theoretical line connecting its two attachments</figcaption>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
## Constraint visualization
|
||||
|
||||
<ConstraintVisualization components={props.components} />
|
||||
|
||||
## Create constraints
|
||||
|
||||
Mover constraints typically connect one or two `Class.Attachment|Attachments` or `Class.Bone|Bones`. When connected to `Class.Bone|Bones`, the constraint will use their animated position and orientation.
|
||||
|
||||
To create a mechanical constraint, you can either insert one from the **Constraint** picker/button or through the [Explorer](../studio/explorer.md) window.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Constraint Picker">
|
||||
|
||||
1. In Studio's **Model** tab toolbar, click‑hold over the small corner arrow on a constraint button to open its picker menu, then select the desired constraint.
|
||||
|
||||
<img src="../assets/studio/general/Toolbar-Constraint-Pickers.png" width="800" alt="Constraint pickers indicated in Studio's toolbar" />
|
||||
|
||||
2. In the 3D viewport, hover over any `Class.Part` or `Class.MeshPart` and click to add a new `Class.Attachment` to the part at the visualized point. Alternatively, hover over and click an existing `Class.Attachment` or `Class.Bone` to use it for the constraint.
|
||||
|
||||
3. Some mover constraints utilize or support a **secondary** attachment in their functionality, so the tool might prompt you to repeat the previous step on another `Class.Part`, `Class.MeshPart`, or `Class.Attachment`, or `Class.Bone`.
|
||||
|
||||
<GridContainer numColumns="2">
|
||||
<figure>
|
||||
<img src="../assets/physics/constraints/Constraint-AngularVelocity-Labeled.jpg" alt="AngularVelocity using one attachment"/>
|
||||
<figcaption>[AngularVelocity](../physics/constraints/angular-velocity.md) using one attachment</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="../assets/physics/constraints/Constraint-AlignPosition-Labeled.jpg" alt="AlignPosition using two attachments"/>
|
||||
<figcaption>[AlignPosition](../physics/constraints/align-position.md) using two attachments</figcaption>
|
||||
</figure>
|
||||
</GridContainer>
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Explorer">
|
||||
|
||||
1. In the [Explorer](../studio/explorer.md) hierarchy, hover over the intended parent, click the **⊕** button, and insert the desired constraint from the dropdown menu, such as a [LinearVelocity](../physics/constraints/linear-velocity.md) constraint.
|
||||
|
||||
<img src="../assets/studio/explorer/LinearVelocity.png" width="320" alt="New LinearVelocity in Explorer window." />
|
||||
|
||||
1. With the new constraint selected, locate its currently empty **Attachment0** property in the [Properties](../studio/properties.md) window.
|
||||
|
||||
<img src="../assets/studio/properties/LinearVelocity-Attachment0-Unassigned.png" width="320" alt="Constraint's Attachment0 property highlighted in Properties window." />
|
||||
|
||||
1. Link the **Attachment0** property to an `Class.Attachment` or `Class.Bone` in two consecutive steps:
|
||||
|
||||
1. In the [Properties](../studio/properties.md) window, click in the **Attachment0** row to reveal the selection cursor.
|
||||
|
||||
2. In the [Explorer](../studio/explorer.md) hierarchy, click on the target `Class.Attachment` or `Class.Bone`.
|
||||
|
||||
<Grid container spacing={3}>
|
||||
<Grid item>
|
||||
<img src="../assets/physics/constraints/LinearVelocity-Link-Attachment0-1.png" width="320" alt="Mouse pointer hovering over Attachment0 property in Properties window." />
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<img src="../assets/physics/constraints/LinearVelocity-Link-Attachment0-2.png" width="320" alt="Target attachment indicated in Explorer window." />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
1. Some mover constraints use or support a **secondary** `Class.Attachment` or `Class.Bone` in their functionality. If necessary, repeat the previous step on the **Attachment1** property in the **Properties** window. For instance:
|
||||
|
||||
- By default, [AlignPosition](../physics/constraints/align-position.md) and [AlignOrientation](../physics/constraints/align-orientation.md) align their primary attachment (**Attachment0**) with a secondary attachment (**Attachment1**).
|
||||
- [LineForce](../physics/constraints/line-force.md) **requires** two attachments to apply force along the theoretical line connecting them.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Physical simulation
|
||||
|
||||
<ConstraintSimulation components={props.components} />
|
||||
|
||||
## Legacy mover conversion
|
||||
|
||||
If your experience relies on legacy `Class.BodyMover`‑based constraints, review the following notes when converting to modern mover constraints.
|
||||
|
||||
<BaseAccordion>
|
||||
<AccordionSummary>`BodyPosition` ⟩ `AlignPosition`</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
`Class.AlignPosition` satisfies the majority of use cases covered by the deprecated `Class.BodyPosition` mover. To sync with how the legacy mover treated each component independently and allowed a different force along each dimension, the `Class.AlignPosition.ForceLimitMode|ForceLimitMode` property of `Class.AlignPosition` allows the constraint to operate in `Enum.ForceLimitMode|Magnitude` mode or `Enum.ForceLimitMode|PerAxis` mode:
|
||||
|
||||
- In `Enum.ForceLimitMode|Magnitude` mode, the existing behavior is preserved and `Class.AlignPosition.MaxForce|MaxForce` is interpreted as a magnitude.
|
||||
|
||||
- In `Enum.ForceLimitMode|PerAxis` mode, the force along each axis can be specified independently. Because the maximum force is specified as a vector, the reference frame of the force can also be specified through the `Class.AlignPosition.ForceRelativeTo|ForceRelativeTo` property with `Enum.ActuatorRelativeTo|World`, `Enum.ActuatorRelativeTo|Attachment0`, and `Enum.ActuatorRelativeTo|Attachment1` options. Additionally, the formulation for the internal controller is modified to match that of `Class.BodyPosition`.
|
||||
</AccordionDetails>
|
||||
</BaseAccordion>
|
||||
|
||||
<BaseAccordion>
|
||||
<AccordionSummary>`BodyGyro` ⟩ `AlignOrientation`</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
`Class.AlignOrientation` satisfies the majority of use cases covered by the deprecated `Class.BodyGyro` mover. The `Class.AlignOrientation.AlignType|AlignType` modes of `Class.AlignOrientation` provide sufficient freedom for most applications and the combination of multiple constraints can replicate the vector torque limit. Additionally, the `Enum.AlignType|PrimaryAxisLookAt` mode forces the primary axis of the constraint's first attachment (`Class.AlignOrientation.Attachment0|Attachment0`) to always point towards the second attachment (`Class.AlignOrientation.Attachment1|Attachment1`), making it a lot easier to add things such as motion tracking security cameras or guided missiles.
|
||||
</AccordionDetails>
|
||||
</BaseAccordion>
|
||||
|
||||
<BaseAccordion>
|
||||
<AccordionSummary>`BodyVelocity` ⟩ `LinearVelocity`</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
`Class.LinearVelocity` satisfies the majority of use cases covered by the deprecated `Class.BodyVelocity` mover. Although the legacy mover allows for a `Class.BodyVelocity.MaxForce|MaxForce` vector, the typical application of that vector force was to zero a particular component, allowing the constraint to be disabled along that dimension. `Class.LinearVelocity` achieves a similar effect by operating in distinct `Class.LinearVelocity.VelocityConstraintMode|VelocityConstraintMode` modes that corresponded to one (`Enum.VelocityConstraintMode|Line`), two (`Enum.VelocityConstraintMode|Plane`), and three (`Enum.VelocityConstraintMode|Vector`) dimensions.
|
||||
|
||||
Additionally, the `Class.LinearVelocity.ForceLimitMode|ForceLimitMode` property with the option of `Enum.ForceLimitMode|PerAxis` accommodates any applications of the vector force with all non‑zero components, such as an increase in the force along a single axis to counteract gravity.
|
||||
</AccordionDetails>
|
||||
</BaseAccordion>
|
||||
|
||||
<BaseAccordion>
|
||||
<AccordionSummary>`BodyAngularVelocity` ⟩ `AngularVelocity`</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
Although `Class.AngularVelocity` has some discrepancies with the deprecated `Class.BodyAngularVelocity` mover, specific cases related to those discrepancies have not been highlighted by the community, nor internally.
|
||||
|
||||
As a separate improvement, `Class.AngularVelocity` works with `Class.Attachment|Attachments` and the `Class.AngularVelocity.RelativeTo|RelativeTo` property lets you specify the `Datatype.CFrame` in which the force is specified, for example `Enum.ActuatorRelativeTo|World` or `Enum.ActuatorRelativeTo|Attachment1`.
|
||||
</AccordionDetails>
|
||||
</BaseAccordion>
|
||||
|
||||
<BaseAccordion>
|
||||
<AccordionSummary>`BodyForce`/`BodyThrust` ⟩ `VectorForce`</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
`Class.VectorForce` satisfies all use cases offered by the deprecated `Class.BodyForce` and `Class.BodyThrust` movers. The modern constraint works with `Class.Attachment|Attachments` and its `Class.VectorForce.RelativeTo|RelativeTo` property lets you apply force to a relative offset from center, similar to how `Class.BodyThrust.Location` worked.
|
||||
</AccordionDetails>
|
||||
</BaseAccordion>
|
||||
|
||||
<BaseAccordion>
|
||||
<AccordionSummary>`RocketPropulsion` ⟩ `LineForce`/`AlignOrientation`</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
A combination of `Class.LineForce` and `Class.AlignOrientation` satisfies the majority of use cases covered by the deprecated `Class.RocketPropulsion` mover. In the example of a guided missile, `Class.LineForce` can be used to control the "follow target" behavior of `Class.RocketPropulsion` while `Class.AlignOrientation` and its `Class.AlignOrientation.LookAtPosition|LookAtPosition` property can be used to control the "face target" behavior.
|
||||
</AccordionDetails>
|
||||
</BaseAccordion>
|
||||
118
.cursor/rules/roblox/en-us/physics/network-ownership.md
Normal file
118
.cursor/rules/roblox/en-us/physics/network-ownership.md
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
---
|
||||
title: Network ownership
|
||||
description: Learn how the Roblox Engine utilizes network ownership to improve physical responsiveness for players.
|
||||
---
|
||||
|
||||
In order to support complex physical mechanisms while also aiming for a smooth and responsive experience for players, the Roblox [physics](../physics/index.md) engine utilizes a **distributed physics** system in which computations are distributed between the server and all connected clients. Within this system, the engine assigns **network ownership** of physically simulated `Class.BasePart|BaseParts` to either a client or server to divide the work of calculating physics.
|
||||
|
||||
Clients experience **more responsive** physics interactions with parts that they own, since there's no latency from communication with the server. Network ownership also improves server performance because physics computations can be split up among individual clients, allowing the server to prioritize other tasks.
|
||||
|
||||
## BasePart ownership
|
||||
|
||||
By default, the server retains ownership of any `Class.BasePart`. Additionally, the server **always** owns anchored `Class.BasePart|BaseParts` and you cannot manually change their ownership.
|
||||
|
||||
Based on a client's hardware capacity and the player's `Class.Player.Character` proximity to an unanchored `Class.BasePart`, the engine automatically assigns ownership of that part to the client. Thus, parts close to a player's character are more likely to become player-owned.
|
||||
|
||||
## Assembly ownership
|
||||
|
||||
If a physics-based mechanism has no anchored parts, [setting ownership](#setting-ownership) on an [assembly](../physics/assemblies.md) within that mechanism sets the same ownership for **every assembly** in the mechanism.
|
||||
|
||||
If you anchor a lone assembly that is **not** part of a broader mechanism, its ownership goes to the server, since the server always owns anchored `Class.BasePart|BaseParts`. Upon unanchoring the same assembly, its previous ownership state is lost and it reverts to automatic handling by the engine.
|
||||
|
||||
If you anchor one assembly within a broader mechanism of assemblies, its ownership goes to the server, but ownership of the other assemblies remains unchanged. Unanchoring the same assembly reverts its previously set ownership.
|
||||
|
||||
## Setting ownership
|
||||
|
||||
In experiences with complex physics interactions or in cases where you need to assign direct control, you can set ownership through a server-side call to `Class.BasePart:SetNetworkOwner()`.
|
||||
|
||||
<Alert severity="info">
|
||||
<p>While you can manually call `Class.BasePart:SetNetworkOwner()|SetNetworkOwner(nil)` for the server for gameplay-critical objects that the client should not be able to manipulate, you should do so conservatively since it may result in jittery physics interactions for clients.</p>
|
||||
Also note that the server **always** owns anchored `Class.BasePart|BaseParts` and you cannot manually change their ownership.
|
||||
</Alert>
|
||||
|
||||
Consider a vehicle that has a `Class.VehicleSeat` object for the driver and a `Class.Seat` object for a passenger, with both included in the vehicle assembly. With the default ownership rules, if a player character sits in the `Class.Seat` (passenger) and then another player jumps into the `Class.VehicleSeat` (driver), the **passenger** gains physical ownership of the entire vehicle because they entered first. The driver will have to wait several network cycles before their input is recognized and the vehicle will feel less responsive.
|
||||
|
||||
The following `Class.Script` fixes this by manually assigning network ownership to the driver. In it, the `Class.VehicleSeat` sets its `Class.VehicleSeat.Occupant|Occupant` to the `Class.Humanoid` sitting on it, so the script listens for the seat's `Class.Instance.Changed|Changed` event to catch when a player sits in the seat. When the driver leaves the seat, the vehicle's network ownership is reverted to automatic with `Class.BasePart:SetNetworkOwnershipAuto()`.
|
||||
|
||||
```lua
|
||||
local Players = game:GetService("Players")
|
||||
|
||||
local vehicleSeat = script.Parent
|
||||
|
||||
vehicleSeat.Changed:Connect(function(prop)
|
||||
if prop == "Occupant" then
|
||||
local humanoid = vehicleSeat.Occupant
|
||||
if humanoid then
|
||||
-- Get the player from the character
|
||||
local player = Players:GetPlayerFromCharacter(humanoid.Parent)
|
||||
if player then
|
||||
vehicleSeat:SetNetworkOwner(player)
|
||||
end
|
||||
else
|
||||
-- Reset ownership when seat is unoccupied
|
||||
vehicleSeat:SetNetworkOwnershipAuto()
|
||||
end
|
||||
end
|
||||
end)
|
||||
```
|
||||
|
||||
<Alert severity="warning">
|
||||
For smooth performance and responsive behavior, ensure you also assign ownership of any loose `Class.BasePart|BaseParts` on top of a vehicle to the same client that controls the vehicle.
|
||||
</Alert>
|
||||
|
||||
## Visualizing ownership
|
||||
|
||||
To assist with network ownership debugging, Studio can render colored outlines around objects when playtesting.
|
||||
|
||||
<video src="../assets/physics/network-ownership/Visualization-Demo.mp4" controls width="90%" alt="Video showing part ownership indicated through colored outlines"></video>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Outline color</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><ColorSwatch value="rgb(30,100,50)" /></td>
|
||||
<td>(green)</td>
|
||||
<td>Your client owns the part and is simulating it.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><ColorSwatch value="rgb(160,0,0)" /></td>
|
||||
<td>(red)</td>
|
||||
<td>The part is within a "buffer zone" where your client is simulating it but it's still owned by something else. Your client might get ownership after this, or it may reject.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><ColorSwatch value="rgb(220,220,220)" /><br /><ColorSwatch value="rgb(140,140,140)" /></td>
|
||||
<td>(white/grey)</td>
|
||||
<td>Server or another client owns the part through either automatic network ownership or from explicit assignment through `Class.BasePart:SetNetworkOwner()|part:SetNetworkOwner()`.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><ColorSwatch value="rgb(0,0,0)" /></td>
|
||||
<td>(black)</td>
|
||||
<td>The part is owned by neither the server nor the client. Physics will not apply to this part.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<Alert severity="info">
|
||||
Note that in a [multi-client simulation](../studio/testing-modes.md#multi-client-simulation), each client is assigned a unique color to indicate their ownership; this is mirrored in the [Server](../studio/testing-modes.md#toggle-clientserver) view, helping you determine which client owns which part(s) at any given time.
|
||||
</Alert>
|
||||
|
||||
To enable network ownership visualization:
|
||||
|
||||
1. Click on the **visualization options** button in the upper-right corner of the 3D viewport.
|
||||
|
||||
<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." />
|
||||
|
||||
2. In the dropdown menu, toggle on **Network owners**.
|
||||
|
||||
## Security concerns
|
||||
|
||||
Roblox cannot verify physics calculations when a client has ownership over a `Class.BasePart`. Clients can exploit this and send bad data to the server, such as teleporting the `Class.BasePart`, making it go through walls or fly around.
|
||||
|
||||
Additionally, `Class.BasePart.Touched` events are tied to network ownership, meaning that a client can fire `Class.BasePart.Touched|Touched` events on a `Class.BasePart` it owns and send it to the server, even if the server doesn't see it touch anything. For example, a client can make a sword deal damage to another player across the map by firing the event through script injections, so it's important to check the validity of such events fired by clients.
|
||||
|
||||
See [Security Tactics and Cheat Mitigation](../scripting/security/security-tactics.md) for detailed security tactics and cheat mitigation tactics for Roblox experiences.
|
||||
148
.cursor/rules/roblox/en-us/physics/sleep-system.md
Normal file
148
.cursor/rules/roblox/en-us/physics/sleep-system.md
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
---
|
||||
title: Sleep system
|
||||
description: Explore how the sleep system automatically prevents unnecessary simulation of non-moving parts.
|
||||
---
|
||||
|
||||
Each [assembly](../physics/assemblies.md) in the Roblox Engine corresponds to a single **rigid body**. The position and velocity of each rigid body describe where it's located and how fast it's moving, and one of the primary engine tasks is to update the positions and velocities of each assembly.
|
||||
|
||||
Assemblies can be connected together with [mechanical constraints](../physics/mechanical-constraints.md) and [mover constraints](../physics/mover-constraints.md) to form mechanisms such as cars or airplanes. As the number of assemblies and constraints in a mechanism increases, the time required to simulate the mechanism also increases. Fortunately, this increase is offset when the **sleep system** determines that the engine can skip simulation of non‑moving assemblies.
|
||||
|
||||
## Sleep states
|
||||
|
||||
Each assembly can be in one of three states: [awake](#awake), [sleeping](#sleeping), or [sleep‑checking](#sleep-checking).
|
||||
|
||||
### Awake
|
||||
|
||||
An **awake** assembly is moving or accelerating, and is therefore simulated. Assemblies enter this state from situations outlined in [sleeping](#sleeping) and [sleep‑checking](#sleep-checking), as well as [additional wake situations](#additional-wake-situations).
|
||||
|
||||
### Sleeping
|
||||
|
||||
A **sleeping** assembly is neither moving nor accelerating, and is therefore not simulated.
|
||||
|
||||
An assembly is determined to be non-moving by checking its **linear velocity** and **rotational velocity**. If its linear velocity is less than the [Linear Velocity](#threshold-reference) threshold and its rotational velocity is less than the [Rotational Velocity](#threshold-reference) threshold, the assembly is considered to be non-moving.
|
||||
|
||||
In some cases, simply checking for non-movement would cause an assembly to incorrectly enter the sleeping state. For example, if a ball is thrown straight up, its velocity approaches zero as it reaches its maximum height, making it a candidate to sleep and never fall back down. To handle such cases, the engine considers an assembly to be accelerating if its **linear acceleration** or **rotational acceleration** are greater than the [Linear Acceleration](#threshold-reference) and [Rotational Acceleration](#threshold-reference) thresholds, respectively, and will prevent the assembly from falling asleep.
|
||||
|
||||
<Alert severity="info">
|
||||
If an assembly falls asleep when you expect it to remain awake, it's commonly because the assembly is moving too slowly. In addition to automatic checks outlined in [sleep‑checking](#sleep-checking) and [sleeping](#sleeping), you can forcibly wake up an assembly through the conditions outlined in [additional wake situations](#additional-wake-situations).
|
||||
</Alert>
|
||||
|
||||
### Sleep-checking
|
||||
|
||||
A non-moving assembly that shares a constraint with at least one [awake](#awake) neighboring assembly is put into the **sleep-checking** state and is not simulated. On each worldstep, a sleep-checking assembly checks whether:
|
||||
|
||||
- Its **linear acceleration** is greater than the [Wake Linear Acceleration](#threshold-reference) threshold.
|
||||
- Its **rotational acceleration** is greater than the [Wake Rotational Acceleration](#threshold-reference) threshold.
|
||||
- A neighboring assembly's **linear velocity** is greater than the [Neighbor Linear Velocity](#threshold-reference) threshold.
|
||||
- A neighboring assembly's **rotational velocity** is greater than the [Neighbor Rotational Velocity](#threshold-reference) threshold.
|
||||
|
||||
If any of these conditions is true, or under any of the [additional wake situations](#additional-wake-situations), the sleep-checking assembly enters the [awake](#awake) state.
|
||||
|
||||
## Threshold reference
|
||||
|
||||
The following table provides the various velocity and acceleration thresholds used to determine if an assembly is moving or accelerating.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Threshold</th>
|
||||
<th>Value</th>
|
||||
<th>State change</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Linear Velocity</td>
|
||||
<td>0.33 studs/s</td>
|
||||
<td>[awake](#awake) ⟩ [sleeping](#sleeping)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rotational Velocity</td>
|
||||
<td>0.42 studs/s</td>
|
||||
<td>[awake](#awake) ⟩ [sleeping](#sleeping)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Linear Acceleration</td>
|
||||
<td>0.24 studs/s²</td>
|
||||
<td>[awake](#awake) ⟩ [sleeping](#sleeping)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rotational Acceleration</td>
|
||||
<td>0.24 studs/s²</td>
|
||||
<td>[awake](#awake) ⟩ [sleeping](#sleeping)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Neighbor Linear Velocity</td>
|
||||
<td>0.48 studs/s</td>
|
||||
<td>[sleep-checking](#sleep-checking) ⟩ [awake](#awake)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Neighbor Rotational Velocity</td>
|
||||
<td>0.59 studs/s</td>
|
||||
<td>[sleep-checking](#sleep-checking) ⟩ [awake](#awake)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Wake Linear Acceleration</td>
|
||||
<td>16.9 studs/s²</td>
|
||||
<td>[awake](#awake) ⟩ [sleeping](#sleeping)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Wake Rotational Acceleration</td>
|
||||
<td>16.9 studs/s²</td>
|
||||
<td>[awake](#awake) ⟩ [sleeping](#sleeping)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Rotational velocity and acceleration thresholds reflect the velocity and acceleration of a point located on the assembly bounding sphere (a sphere that contains all of the parts in an assembly) that moves rigidly with the assembly.
|
||||
|
||||
<Alert severity="info">
|
||||
For a given angular velocity, the rotational velocity of an assembly is proportional to the assembly bounding sphere radius. This means that larger assemblies can rotate at a lower angular velocity without falling asleep.
|
||||
</Alert>
|
||||
|
||||
## Additional wake situations
|
||||
|
||||
In addition to situations outlined in [sleep‑checking](#sleep-checking) and [sleeping](#sleeping), an assembly enters the [awake](#awake) state when:
|
||||
|
||||
- It collides with another assembly moving faster than 1 studs/s.
|
||||
- Any physics-related property of any `Class.BasePart` within the assembly changes, including:
|
||||
|
||||
- `Class.BasePart.Anchored|Anchored`
|
||||
- `Class.BasePart.AssemblyLinearVelocity|AssemblyLinearVelocity`/`Class.BasePart.AssemblyAngularVelocity|AssemblyAngularVelocity`
|
||||
- `Class.BasePart.CanCollide|CanCollide`/`Class.BasePart.CanTouch|CanTouch`
|
||||
- `Class.BasePart.CustomPhysicalProperties|CustomPhysicalProperties`
|
||||
- `Class.BasePart.EnableFluidForces|EnableFluidForces`
|
||||
- `Class.BasePart.Massless|Massless`
|
||||
- `Class.BasePart.RootPriority|RootPriority`
|
||||
|
||||
- A non-zero impulse is applied to any `Class.BasePart` within the assembly via `Class.BasePart:ApplyImpulse()|ApplyImpulse()`, `Class.BasePart:ApplyImpulseAtPosition()|ApplyImpulseAtPosition()`, or `Class.BasePart:ApplyAngularImpulse()|ApplyAngularImpulse()`.
|
||||
|
||||
- Any physics-related property changes on the `Class.Workspace` that would affect the assembly, including:
|
||||
|
||||
- `Class.Workspace.Gravity|Gravity`
|
||||
- `Class.Workspace.FluidForces|FluidForces`
|
||||
- `Class.Workspace.GlobalWind|GlobalWind`
|
||||
- `Class.Workspace.AirDensity|AirDensity`
|
||||
|
||||
- A new `Class.Constraint` is created with an `Class.Attachment` that is parented to a `Class.BasePart` within the assembly.
|
||||
|
||||
- Any property changes for a `Class.Constraint` with an `Class.Attachment` that is parented to a `Class.BasePart` within the assembly.
|
||||
|
||||
- The `Class.Motor.CurrentAngle|CurrentAngle` property changes for a `Class.Motor` that is connected to a `Class.BasePart` within the assembly.
|
||||
|
||||
- The assembly contains a `Class.VehicleSeat` with a seated player character.
|
||||
|
||||
- The assembly is within the `Class.Explosion.BlastRadius|BlastRadius` of an `Class.Explosion`.
|
||||
|
||||
## Debug visualization
|
||||
|
||||
During playtesting, you can visualize assembly sleep states by toggling on **Awake parts** from the [Visualization Options](../studio/ui-overview.md#visualization-options) widget in the upper‑right corner of the 3D viewport.
|
||||
|
||||
<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." />
|
||||
|
||||
Once enabled, simulated parts will be outlined by their current sleep state, with [awake](#awake) parts outlined in red, [sleep‑checking](#sleep-checking) parts outlined in orange, and [sleeping](#sleeping) parts un‑outlined.
|
||||
|
||||
<figure>
|
||||
<video src="../assets/physics/assemblies/Sleep-Demo.mp4" controls width="800"></video>
|
||||
<figcaption>Simulated parts outlined by the color representing their current sleep state</figcaption>
|
||||
</figure>
|
||||
184
.cursor/rules/roblox/en-us/physics/units.md
Normal file
184
.cursor/rules/roblox/en-us/physics/units.md
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
---
|
||||
title: Roblox units
|
||||
description: Explore the physical units used in Roblox and how they convert to metric units.
|
||||
---
|
||||
|
||||
This article outlines Roblox physical units and how they convert to metric units. Understanding units is useful whenever you work with physics, as in the following examples:
|
||||
|
||||
- Customizing your experience's gravity, jump height/power, and walk speed in the **World** tab of Studio's **File** ⟩ **Experience Settings** window.
|
||||
- Tuning linear/angular velocities, forces, torques, stiffness, and damping of [mechanical constraints](../physics/mechanical-constraints.md) and [mover constraints](../physics/mover-constraints.md).
|
||||
- Adjusting the density of [custom materials](../parts/materials.md#custom-materials).
|
||||
|
||||
## Unit conversions
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Primary Units">
|
||||
|
||||
In general, you can use the conversions in the following table to relate Roblox's primary units for time, length, and mass to their metric counterparts.
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Unit</th>
|
||||
<th>Roblox</th>
|
||||
<th>Metric</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Time**</td>
|
||||
<td>1 second</td>
|
||||
<td>1 second</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Length**</td>
|
||||
<td>1 stud</td>
|
||||
<td>28 cm</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Mass**</td>
|
||||
<td>1 RMU*</td>
|
||||
<td>21.952 kg</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<figcaption>\* RMU = Roblox Mass Unit</figcaption>
|
||||
</TabItem>
|
||||
<TabItem label="Derived units">
|
||||
|
||||
The primary units are used to generate conversions for **derived** units such as water density and air pressure at standard conditions. The following physical properties are expressed in metric units and Roblox units, with primary unit equivalents provided in brackets. All conversions have been rounded to three significant figures.
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Unit</th>
|
||||
<th>Metric</th>
|
||||
<th>Roblox</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Water Density**</td>
|
||||
<td>1 g/cm³</td>
|
||||
<td>1 RMU/stud³</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Air Density** (sea level)</td>
|
||||
<td>0.00129 g/cm³</td>
|
||||
<td>0.00129 RMU/stud³</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**1 atmosphere**</td>
|
||||
<td>101,325 Pa *[kg/(m s²)]*</td>
|
||||
<td>1290 RMU/(stud s²)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Spring Stiffness**</td>
|
||||
<td>1 N/m *[kg/s²]*</td>
|
||||
<td>0.0456 RMU/s²</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Spring Damping**</td>
|
||||
<td>1 N s/m *[kg/s]*</td>
|
||||
<td>0.0456 RMU/s</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Velocity**</td>
|
||||
<td>1 m/s</td>
|
||||
<td>3.57 studs/s</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Force**</td>
|
||||
<td>1 N *[kg m/s²]*</td>
|
||||
<td>0.163 Rowtons *[RMU stud/s²]*</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Torque**</td>
|
||||
<td>1 N-m *[kg m²/s²]*</td>
|
||||
<td>0.581 Rowton-studs *[RMU stud²/s²]*</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</TabItem>
|
||||
<TabItem label="Gravity">
|
||||
|
||||
The following table illustrates gravitational acceleration in Roblox units and metric units for presets in the **World** tab of Studio's **File** ⟩ **Experience Settings** window.
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Preset</th>
|
||||
<th>Roblox</th>
|
||||
<th>Metric</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Classic** (default)</td>
|
||||
<td>196.2 studs/s²</td>
|
||||
<td>54.963 m/s²</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Realistic** (real-world)</td>
|
||||
<td>35 studs/s²</td>
|
||||
<td>9.8 m/s²</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Action**</td>
|
||||
<td>75 studs/s²</td>
|
||||
<td>21 m/s²</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</TabItem>
|
||||
<TabItem label="Physical limits">
|
||||
|
||||
Roblox places limits on certain physical properties, as outlined in the following table. Details on these properties is located in the `Datatype.PhysicalProperties` documentation.
|
||||
|
||||
<table size="small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Property</th>
|
||||
<th>Minimum</th>
|
||||
<th>Maximum</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>**Density** (RMU/stud³)</td>
|
||||
<td>0.0001</td>
|
||||
<td>100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Friction**</td>
|
||||
<td>0.0</td>
|
||||
<td>2.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Friction Weight**</td>
|
||||
<td>0.0</td>
|
||||
<td>100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Elasticity**</td>
|
||||
<td>0.0</td>
|
||||
<td>1.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>**Elasticity Weight**</td>
|
||||
<td>0.0</td>
|
||||
<td>100</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Importance of unit consistency
|
||||
|
||||
Internally, the Roblox physics engine does not use unit conversions. You're free to define your own unit interpretations for studs (length) and RMUs (mass), but these should be used in a consistent manner throughout the experience. For example, if you decide that one stud equals one foot (30.483 cm), the unit density of water implies an RMU is equal to 62.4 lbs (28.3 kg):
|
||||
|
||||
<blockquote>
|
||||
1 (g/cm³) × (30.48³ cm³/ft³) = 28,317 (g/ft³) × (0.00220462 lbs/g) = 62.4 (lbs/ft³) = 1 (RMU/stud³)
|
||||
</blockquote>
|
||||
|
||||
Overall, it's recommended that you use standard Roblox units because it makes an experience work as expected in all scenarios, such as compatibility with VR controls.
|
||||
Loading…
Add table
Add a link
Reference in a new issue