diff --git a/content/en-us/luau/metatables.md b/content/en-us/luau/metatables.md
index 7817cb3c8..022c5f1d2 100644
--- a/content/en-us/luau/metatables.md
+++ b/content/en-us/luau/metatables.md
@@ -80,7 +80,7 @@ Here's the list of available metamethods:
__mul(table, value) |
- The * mulitplication operator. |
+ The * multiplication operator. |
__div(table, value) |
diff --git a/content/en-us/luau/queues.md b/content/en-us/luau/queues.md
index 1e95b66b6..0121a0582 100644
--- a/content/en-us/luau/queues.md
+++ b/content/en-us/luau/queues.md
@@ -58,20 +58,20 @@ function Queue.new(): Queue
end
-- Check if the queue is empty
-function Queue.IsEmpty(self: Queue)
+function Queue.isEmpty(self: Queue)
return self._first > self._last
end
-- Add a value to the queue
-function Queue.Enqueue(self: Queue, value: T)
+function Queue.enqueue(self: Queue, value: T)
local last = self._last + 1
self._last = last
self._queue[last] = value
end
-- Remove a value from the queue
-function Queue.Dequeue(self: Queue): T
- if self:IsEmpty() then
+function Queue.dequeue(self: Queue): T
+ if self:isEmpty() then
error("Cannot dequeue from empty queue")
end
@@ -96,27 +96,27 @@ local Queue = require(ReplicatedStorage:WaitForChild("Queue"))
local myQueue = Queue.new()
-- Add some values to the queue
-myQueue:Enqueue(5)
-myQueue:Enqueue(10)
-myQueue:Enqueue(15)
+myQueue:enqueue(5)
+myQueue:enqueue(10)
+myQueue:enqueue(15)
-- myQueue = { 5, 10, 15 }
-- Remove one value from the queue
-local first = myQueue:Dequeue()
+local first = myQueue:dequeue()
print("The first value added to the queue was", first)
-- myQueue = { 10, 15 }
-- Add more values to the queue
-myQueue:Enqueue(20)
-myQueue:Enqueue(25)
-myQueue:Enqueue(30)
+myQueue:enqueue(20)
+myQueue:enqueue(25)
+myQueue:enqueue(30)
-- myQueue = { 10, 15, 20, 25, 30 }
-- Remove another value from the queue
-local second = myQueue:Dequeue()
+local second = myQueue:dequeue()
print("The second value added to the queue was", second)
-- myQueue = { 15, 20, 25, 30 }
diff --git a/content/en-us/luau/stacks.md b/content/en-us/luau/stacks.md
index 99b582a62..ddc2f75f1 100644
--- a/content/en-us/luau/stacks.md
+++ b/content/en-us/luau/stacks.md
@@ -26,18 +26,18 @@ function Stack.new()
end
-- Check if the stack is empty
-function Stack:IsEmpty()
+function Stack:isEmpty()
return #self._stack == 0
end
-- Put a new value onto the stack
-function Stack:Push(value)
+function Stack:push(value)
table.insert(self._stack, value)
end
-- Take a value off the stack
-function Stack:Pop()
- if self:IsEmpty() then
+function Stack:pop()
+ if self:isEmpty() then
return nil
end
@@ -57,21 +57,21 @@ local s = Stack.new()
-- Change the stack Resulting stack Output
-s:Push(1) -- {1}
+s:push(1) -- {1}
-s:Push(5) -- {1, 5}
+s:push(5) -- {1, 5}
-s:Push(10) -- {1, 5, 10}
+s:push(10) -- {1, 5, 10}
-print(s:Pop()) -- {1, 5} 10
+print(s:pop()) -- {1, 5} 10
-print(s:Pop()) -- {1} 5
+print(s:pop()) -- {1} 5
-s:Push(20) -- {1, 20}
+s:push(20) -- {1, 20}
-print(s:Pop()) -- {1} 20
+print(s:pop()) -- {1} 20
-print(s:Pop()) -- {} 1
+print(s:pop()) -- {} 1
```
diff --git a/content/en-us/luau/tables.md b/content/en-us/luau/tables.md
index 6acd31b5c..de60d66b7 100644
--- a/content/en-us/luau/tables.md
+++ b/content/en-us/luau/tables.md
@@ -141,9 +141,9 @@ To create a dictionary table, define each **key** followed by `=` and the **valu
```lua
local testDictionary = {
- FruitName = "Lemon",
- FruitColor = "Yellow",
- Sour = true
+ fruitName = "Lemon",
+ fruitColor = "Yellow",
+ sour = true
}
```
@@ -153,7 +153,7 @@ The keys for dictionaries can be numbers, strings, and objects. For example, a k
local part = Instance.new("Part")
local testDictionary = {
- PartType = "Block",
+ partType = "Block",
[part] = true
}
```
@@ -166,11 +166,11 @@ To read from a dictionary, add a pair of brackets after its reference and specif
local part = Instance.new("Part")
local testDictionary = {
- PartType = "Block",
+ partType = "Block",
[part] = true
}
-- Include quotes for string keys
-print(testDictionary["PartType"]) -- Block
+print(testDictionary["partType"]) -- Block
-- Omit quotes for non-string keys
print(testDictionary[part]) -- true
```
@@ -181,20 +181,20 @@ To define or rewrite the value of a new or existing dictionary key, declare the
```lua
local testDictionary = {
- FruitName = "Lemon",
- Sour = true
+ fruitName = "Lemon",
+ sour = true
}
-- Change value of existing keys
-testDictionary["FruitName"] = "Cherry"
-testDictionary["Sour"] = false
+testDictionary["fruitName"] = "Cherry"
+testDictionary["sour"] = false
-- Insert new key-value pair
-testDictionary["FruitCount"] = 10
+testDictionary["fruitCount"] = 10
-print(testDictionary["FruitName"]) -- Cherry
-print(testDictionary["Sour"]) -- false
-print(testDictionary["FruitCount"]) -- 10
+print(testDictionary["fruitName"]) -- Cherry
+print(testDictionary["sour"]) -- false
+print(testDictionary["fruitCount"]) -- 10
```
### Iterating over Dictionaries
@@ -203,9 +203,9 @@ To iterate over a dictionary, use the global `pairs()` function in a `for` loop:
```lua
local testDictionary = {
- FruitName = "Lemon",
- FruitColor = "Yellow",
- Sour = true
+ fruitName = "Lemon",
+ fruitColor = "Yellow",
+ sour = true
}
for key, value in pairs(testDictionary) do
@@ -213,9 +213,9 @@ for key, value in pairs(testDictionary) do
end
--[[ Resulting output:
-FruitName Lemon
-Sour true
-FruitColor Yellow
+fruitName Lemon
+sour true
+fruitColor Yellow
]]
```
@@ -229,19 +229,19 @@ To remove or erase a key-value pair from a dictionary, set its value for a key t
```lua
local testDictionary = {
- FruitName = "Lemon",
- FruitColor = "Yellow",
- Sour = true
+ fruitName = "Lemon",
+ fruitColor = "Yellow",
+ sour = true
}
-testDictionary["Sour"] = nil
+testDictionary["sour"] = nil
for key, value in pairs(testDictionary) do
print(key, value)
end
--[[ Resulting output:
-FruitName Lemon
-FruitColor Yellow
+fruitName Lemon
+fruitColor Yellow
]]
```
diff --git a/content/en-us/projects/transferring-animations.md b/content/en-us/projects/transferring-animations.md
index 67d184cb2..7e00dbc74 100644
--- a/content/en-us/projects/transferring-animations.md
+++ b/content/en-us/projects/transferring-animations.md
@@ -3,13 +3,13 @@ title: Transferring Roblox Animations
description: Transfer animations when you transfer your experience to a new group owner.
---
-
+
The instructions on this page make use of a third-party tool. Roblox does not officially support this tool and is not responsible for its availability, updates, or functionality.
In Roblox, animations are locked to experiences owned by users who also own those animations. To prevent animations from breaking when you transfer your experience to a group, you must publish your animation assets to the new experience group owner.
-If you have a large number of animations to upload, you can use the community-supported tool [Roblox Animation Transfer](https://github.com/evaera/roblox-animation-transfer) to re-upload the animations and map their old `AnimationIds` to their new corresponding `AnimationIds`.
+If you have a large number of animations to upload, you can use the community-supported tool [Roblox Animation Transfer](https://github.com/evaera/roblox-animation-transfer) to re-upload the animations and map their old `Class.Animation.AnimationId|AnimationIds` to their new corresponding `Class.Animation.AnimationId|AnimationIds`.
## Prerequisites
@@ -19,33 +19,35 @@ For more information about prerequisites, see the [Roblox Animation Transfer REA
## Mapping AnimationIds to Names
-If your animations are stored as Animation instances under pre-prepared Character models in your experience, you can generate a text file to map the `AnimationIds` to their corresponding names.
+If your animations are stored as Animation instances under pre-prepared Character models in your experience, you can generate a text file to map the `Class.Animation.AnimationId|AnimationIds` to their corresponding names.
1. In Roblox Studio, run the following script. Studio outputs the result as a single long string.
-```lua
-local ANIMSTRING = ""
-
-for _, character in pairs(workspace:GetChildren()) do
- if not character:IsA("Model") then
- continue
- end
-
- local animations = character:FindFirstChild("Animations")
- if not animations then
- continue
- end
-
- for _, animation in pairs(animations:GetChildren()) do
- local animationId = string.match(animation.AnimationId, "%d+")
- if animationId then
- ANIMSTRING ..= (animationId .. " " .. character.Name .. "_" .. string.gsub(animation.Name, " ", "_") .. "\n")
+ ```lua
+ local Workspace = game:GetService("Workspace")
+
+ local ANIMSTRING = ""
+
+ for _, character in Workspace:GetChildren() do
+ if not character:IsA("Model") then
+ continue
end
- end
-end
-
-print(ANIMSTRING)
-```
+
+ local animations = character:FindFirstChild("Animations")
+ if not animations then
+ continue
+ end
+
+ for _, animation in animations:GetChildren() do
+ local animationId = string.match(animation.AnimationId, "%d+")
+ if animationId then
+ ANIMSTRING ..= (animationId .. " " .. character.Name .. "_" .. string.gsub(animation.Name, " ", "_") .. "\n")
+ end
+ end
+ end
+
+ print(ANIMSTRING)
+ ```
2. Create a new text file on your computer.
3. Paste the string output by Studio into the text file.
@@ -81,68 +83,68 @@ After transferring your animations to the new group owner, you must swap the old
2. Create two child modules, one corresponding to the user, or the original owner, and the other corresponding to the group, or the new owner.
3. To prevent the experience from breaking if you choose to publish it to another location, run the following script. By default, the script returns the user's animations.
-```lua
-local module = {}
-local GROUP_ID = 12345678
-local gameContext = {
- ["User"] = require(script:WaitForChild("Animations_User")),
- ["Group"] = require(script:WaitForChild("Animations_Group"))
-}
-
-local function getAnimationMapForGameContext()
- if game.CreatorType == Enum.CreatorType.Group and game.CreatorId == GROUP_ID then
- return gameContext.Group
+ ```lua
+ local module = {}
+ local GROUP_ID = 12345678
+ local gameContext = {
+ ["User"] = require(script:WaitForChild("Animations_User")),
+ ["Group"] = require(script:WaitForChild("Animations_Group"))
+ }
+
+ local function getAnimationMapForGameContext()
+ if game.CreatorType == Enum.CreatorType.Group and game.CreatorId == GROUP_ID then
+ return gameContext.Group
+ end
+ return gameContext.User
end
- return gameContext.User
-end
-
-local animationMap = getAnimationMapForGameContext()
-function module.getAnimation(animName: string)
- return animationMap[animName]
-end
-
-return module
-```
+
+ local animationMap = getAnimationMapForGameContext()
+ function module.getAnimation(animName: string)
+ return animationMap[animName]
+ end
+
+ return module
+ ```
4. Turn the generated text files into animation maps in Studio.
1. Replace the animation list inside the `animFileText` variable with the contents of the text file that you want to change into an animation map.
2. Run the following script to return a string:
-```lua
-local animFileText = [[
-4215167 Animation_Name_1
-6171235 Animation_Name_2
-1251267 Animation_Name_3
-]]
-
-local function convertFileToAnimationMap(animFileText: string)
- local NEW_ANIMATION_MAP = ""
-
- local lines = string.split(animFileText, "\n")
- for _, line in pairs(lines) do
- local components = string.split(line, " ")
- if #components ~= 2 then
- continue
+ ```lua
+ local animFileText = [[
+ 4215167 Animation_Name_1
+ 6171235 Animation_Name_2
+ 1251267 Animation_Name_3
+ ]]
+
+ local function convertFileToAnimationMap(animFileText: string)
+ local NEW_ANIMATION_MAP = ""
+
+ local lines = string.split(animFileText, "\n")
+ for _, line in lines do
+ local components = string.split(line, " ")
+ if #components ~= 2 then
+ continue
+ end
+
+ local animationId = components[1]
+ local animationName = components[2]
+
+ NEW_ANIMATION_MAP = string.format("%s\t[\"%s\"] = \"rbxassetid://%s\",\n", NEW_ANIMATION_MAP, animationName, animationId)
end
-
- local animationId = components[1]
- local animationName = components[2]
-
- NEW_ANIMATION_MAP = string.format("%s\t[\"%s\"] = \"rbxassetid://%s\",\n", NEW_ANIMATION_MAP, animationName, animationId)
+
+ return string.format("return {\n%s}", NEW_ANIMATION_MAP)
end
+
+ print(convertFileToAnimationMap(animFileText))
+ ```
- return string.format("return {\n%s}", NEW_ANIMATION_MAP)
-end
-
-print(convertFileToAnimationMap(animFileText))
-```
-
-5. Create a new `ModuleScript` parented to your `Animations` module.
-6. Place the returned `animFileText` string inside the `ModuleScript`.
+5. Create a new `Class.ModuleScript` parented to your `Animations` module.
+6. Place the returned `animFileText` string inside the `Class.ModuleScript`.
7. Update the experience to source all animations through the `Animations` module by running the following script:
-```lua
-local Animations = require(PATH.TO.ANIMATIONS)
-local warriorWalk = Instance.new("Animation")
-warriorWalk.AnimationId = Animations.getAnimation("Warrior_Walk")
-```
+ ```lua
+ local Animations = require(PATH.TO.ANIMATIONS)
+ local warriorWalk = Instance.new("Animation")
+ warriorWalk.AnimationId = Animations.getAnimation("Warrior_Walk")
+ ```
diff --git a/content/en-us/reference/engine/enums/RollOffMode.yaml b/content/en-us/reference/engine/enums/RollOffMode.yaml
index 816641ab4..d0c64561d 100644
--- a/content/en-us/reference/engine/enums/RollOffMode.yaml
+++ b/content/en-us/reference/engine/enums/RollOffMode.yaml
@@ -15,7 +15,9 @@ items:
- name: Inverse
summary: |
Volume attenuates from `Class.Sound.RollOffMinDistance` in an inverse
- manner. This option mirrors how sounds attenuate in the real world.
+ manner, mirroring how sounds attenuate in the real world.
+ This is done through `Class.Sound.RollOffMinDistance`/`distance`,
+ where `distance` is the `Datatype.Vector3.Magnitude` between the audio source and the audio listener.
value: 0
tags: []
deprecation_message: ''
@@ -23,6 +25,8 @@ items:
summary: |
Volume attenuates between `Class.Sound.RollOffMinDistance` and
`Class.Sound.RollOffMaxDistance` with a linear relationship.
+ This is done through (`Class.Sound.RollOffMaxDistance`/`distance`)/(`Class.Sound.RollOffMaxDistance`-`Class.Sound.RollOffMinDistance`),
+ where `distance` is the `Datatype.Vector3.Magnitude` between the audio source and the audio listener.
value: 1
tags: []
deprecation_message: ''
@@ -30,6 +34,7 @@ items:
summary: |
Volume attenuates between `Class.Sound.RollOffMinDistance` and
`Class.Sound.RollOffMaxDistance` with a linear squared relationship.
+ This is done through squaring `Linear`.
value: 2
tags: []
deprecation_message: ''
@@ -38,6 +43,7 @@ items:
A hybrid model which follows the `Inverse` model when close to
`Class.Sound.RollOffMinDistance` and the `LinearSquare` model when close
to `Class.Sound.RollOffMaxDistance`.
+ This is done by taking the lesser of `Inverse` and `LinearSquare`.
value: 3
tags: []
deprecation_message: ''
diff --git a/content/en-us/reference/engine/libraries/vector.yaml b/content/en-us/reference/engine/libraries/vector.yaml
new file mode 100644
index 000000000..bee00a3f7
--- /dev/null
+++ b/content/en-us/reference/engine/libraries/vector.yaml
@@ -0,0 +1,227 @@
+name: vector
+type: library
+summary: |
+ A library of vector functions.
+description: |
+ This library implements functionality for the vector type in addition to the built-in primitive operator support. It uses vectors with three components (`x`, `y`, and `z`).
+
+ Individual vector components can be accessed using the fields `x` or `X`, `y` or `Y`, `z` or `Z`. Since vector values are immutable, writing to individual components is not supported.
+code_samples:
+properties:
+ - name: vector.zero
+ type: vector
+ summary: Constant vector with all components set to `0`.
+ description: Constant vector with all components set to `0`.
+ tags:
+ code_samples:
+ - name: vector.one
+ type: vector
+ summary: Constant vector with all components set to `1`.
+ description: Constant vector with all components set to `1`.
+ tags:
+ code_samples:
+functions:
+ - name: vector.create
+ summary: Creates a new vector with the given component values.
+ description: Creates a new vector with the given component values.
+ parameters:
+ - name: x
+ type: number
+ default:
+ summary: ''
+ - name: y
+ type: number
+ default:
+ summary: ''
+ - name: z
+ type: number
+ default:
+ summary: ''
+ returns:
+ - type: vector
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.magnitude
+ summary: Calculates the magnitude of a given vector.
+ description: Calculates the magnitude of a given vector.
+ parameters:
+ - name: vec
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: number
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.normalize
+ summary: Computes the normalized version (unit vector) of a given vector.
+ description: Computes the normalized version (unit vector) of a given vector.
+ parameters:
+ - name: vec
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: vector
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.cross
+ summary: Computes the cross product of two vectors.
+ description: Computes the cross product of two vectors.
+ parameters:
+ - name: vec1
+ type: vector
+ default:
+ summary: ''
+ - name: vec2
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: vector
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.dot
+ summary: Computes the dot product of two vectors.
+ description: Computes the dot product of two vectors.
+ parameters:
+ - name: vec1
+ type: vector
+ default:
+ summary: ''
+ - name: vec2
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: number
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.angle
+ summary: Computes the angle between two vectors in radians.
+ description: |
+ Computes the angle between two vectors in radians. The axis, if specified, is used to determine the sign of the angle.
+ parameters:
+ - name: vec1
+ type: vector
+ default:
+ summary: ''
+ - name: vec2
+ type: vector
+ default:
+ summary: ''
+ - name: axis
+ type: vector?
+ default:
+ summary: ''
+ returns:
+ - type: number
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.floor
+ summary: Applies `Library.math.floor()` to every component of the input vector.
+ description: Applies `Library.math.floor()` to every component of the input vector.
+ parameters:
+ - name: vec
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: vector
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.ceil
+ summary: Applies `Library.math.ceil()` to every component of the input vector.
+ description: Applies `Library.math.ceil()` to every component of the input vector.
+ parameters:
+ - name: vec
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: vector
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.abs
+ summary: Applies `Library.math.abs()` to every component of the input vector.
+ description: Applies `Library.math.abs()` to every component of the input vector.
+ parameters:
+ - name: vec
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: vector
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.sign
+ summary: Applies `Library.math.sign()` to every component of the input vector.
+ description: Applies `Library.math.sign()` to every component of the input vector.
+ parameters:
+ - name: vec
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: vector
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.clamp
+ summary: Applies `Library.math.clamp()` to every component of the input vector.
+ description: Applies `Library.math.clamp()` to every component of the input vector.
+ parameters:
+ - name: vec
+ type: vector
+ default:
+ summary: ''
+ - name: min
+ type: vector
+ default:
+ summary: ''
+ - name: max
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: vector
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.max
+ summary: Applies `Library.math.max()` to the corresponding components of the input vectors.
+ description: |
+ Applies `Library.math.max()` to the corresponding components of the input vectors.
+ parameters:
+ - name: ...
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: vector
+ summary: ''
+ tags:
+ code_samples:
+ - name: vector.min
+ summary: Applies `Library.math.min()` to the corresponding components of the input vectors.
+ description: |
+ Applies `Library.math.min()` to the corresponding components of the input vectors.
+ parameters:
+ - name: ...
+ type: vector
+ default:
+ summary: ''
+ returns:
+ - type: vector
+ summary: ''
+ tags:
+ code_samples:
\ No newline at end of file
diff --git a/content/en-us/resources/feature-packages/bundles.md b/content/en-us/resources/feature-packages/bundles.md
index 262e1c731..c78ac49ad 100644
--- a/content/en-us/resources/feature-packages/bundles.md
+++ b/content/en-us/resources/feature-packages/bundles.md
@@ -122,7 +122,7 @@ end
local function initializePurchaseHandlers()
local bundles = Bundles.getBundles()
- for bundleId, bundle in pairs(bundles) do
+ for bundleId, bundle in bundles do
-- Bundle is not associated with a developer product if it does not have marketplace price type
if not bundle or bundle.pricing.priceType ~= "Marketplace" then
continue
@@ -133,7 +133,7 @@ local function initializePurchaseHandlers()
end
-- If you have any in-experience currencies that you are using for bundles, set the handler here
- for currencyId, _ in pairs(Currencies) do
+ for currencyId, _ in Currencies do
Bundles.setInExperiencePurchaseHandler(currencyId, awardInExperiencePurchase)
end
end
@@ -286,7 +286,7 @@ You mainly need to hook up four things once dragging the **Bundles** feature pac
local function initializePurchaseHandlers()
local bundles = Bundles.getBundles()
- for bundleId, bundle in pairs(bundles) do
+ for bundleId, bundle in bundles do
-- Bundle is not associated with a developer product if it does not have marketplace price type
if not bundle or bundle.pricing.priceType ~= "Marketplace" then
continue
@@ -297,7 +297,7 @@ You mainly need to hook up four things once dragging the **Bundles** feature pac
end
-- If you have any in-experience currencies that you are using for bundles, set the handler here
- for currencyId, _ in pairs(Currencies) do
+ for currencyId, _ in Currencies do
Bundles.setInExperiencePurchaseHandler(currencyId, awardInExperiencePurchase)
end
end
diff --git a/content/en-us/workspace/collisions.md b/content/en-us/workspace/collisions.md
index 7635f2e11..9342106ae 100644
--- a/content/en-us/workspace/collisions.md
+++ b/content/en-us/workspace/collisions.md
@@ -262,27 +262,27 @@ interesting but unintended gameplay, such as characters jumping on top of each o
local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
-PhysicsService:RegisterCollisionGroup("Characters")
-PhysicsService:CollisionGroupSetCollidable("Characters", "Characters", false)
-
-local function onDescendantAdded(descendant)
- -- Set collision group for any part descendant
- if descendant:IsA("BasePart") then
- descendant.CollisionGroup = "Characters"
+local CollisionGroupName = "Characters"
+PhysicsService:RegisterCollisionGroup(CollisionGroupName)
+PhysicsService:CollisionGroupSetCollidable(CollisionGroupName, CollisionGroupName, false)
+
+local function setCollisionGroup(model)
+ -- Apply collision group to all existing parts in the model
+ for _, descendant in model:GetDescendants() do
+ if descendant:IsA("BasePart") then
+ descendant.CollisionGroup = CollisionGroupName
+ end
end
end
-local function onCharacterAdded(character)
- -- Process existing and new descendants for physics setup
- for _, descendant in character:GetDescendants() do
- onDescendantAdded(descendant)
- end
- character.DescendantAdded:Connect(onDescendantAdded)
-end
-
Players.PlayerAdded:Connect(function(player)
- -- Detect when the player's character is added
- player.CharacterAdded:Connect(onCharacterAdded)
+ player.CharacterAdded:Connect(function(character)
+ setCollisionGroup(character)
+ end)
+ -- If the player already has a character, apply the collision group immediately
+ if player.Character then
+ setCollisionGroup(player.Character)
+ end
end)
```
@@ -360,4 +360,4 @@ The `Class.TriangleMeshPart.CollisionFidelity|CollisionFidelity` property has th
To view collision fidelity in Studio, toggle on **Collision fidelity** from the [Visualization Options](../studio/ui-overview.md#visualization-options) widget in the upper‑right corner of the 3D viewport.
-For more information on the performance impact of collision fidelity options and how to mitigate them, see [Performance Optimization](../performance-optimization/improving.md#physics-computation). For an in‑depth walkthrough on how to choose a collision fidelity option that balances your precision needs and performance requirements, see [here](../tutorials/environmental-art/assemble-an-asset-library.md#collisionfidelity).
+For more information on the performance impact of collision fidelity options and how to mitigate them, see [Performance Optimization](../performance-optimization/improving.md#physics-computation).