Trying to make a script so that the parts of the character are canCollide = false.
I made this but not sure how to proceed:
-- StarterCharacterScripts
local character = script.Parent
local parts = character:GetChildren()
Trying to make a script so that the parts of the character are canCollide = false.
I made this but not sure how to proceed:
-- StarterCharacterScripts
local character = script.Parent
local parts = character:GetChildren()
Note:
I realise I can just manually change the parts cancollide property like;
HumanoidRootPart.CanCollide = false
Torso.CanCollide = false
But I am trying to learn how to use the getChildren function.
Instead of disabling collisions completely, I believe you are actually looking to assign them to a special collision group where parts cannot collide with themselves. Setting CanCollide itself would make the characters fall through the floor.
Firstly, create a collision group, either via a script or in the collision group editor. The code below should be quite self explainatory: the registration of a Players
group if there isn’t one, and disabling collisions between members of the same group.
local PhysicsService = game:GetService("PhysicsService")
local PlayerService = game:GetService("Players")
if not PhysicsService:IsCollisionGroupRegistered("Players") then
PhysicsService:RegisterCollisionGroup("Players")
end
PhysicsService:CollisionGroupSetCollidable("Players", "Players", false)
Each time a new character spawns, iterate through all parts and set their collision group.
Just like GetChildren()
, GetDescedants()
returns a flat array of descendants (which include children’s children, and further - all objects in the hierarchical tree). I thought GetDescendants()
would also cover accessories, whose handles (BaseParts) are not immediate children of a character.
Because during the game parts might be added to the character, to cover those cases, a listener is connected to DescedantAdded
, firing every time a new descendant becomes a member of the character.
-- the loop
for _,part in character:GetDescendants() do
if part:IsA("BasePart") then
part.CollisionGroup = "Players"
end
end
-- the future descendants
character.DescendantAdded:Connect(function(descendant)
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Players"
end
end)
About memory leaks:
The signal connections don’t disconnect themselves. They cease to be active once they are disconnected manually by calling :Disconnect()
, or when the instance they are bound to is destroyed.
As evident from the announcement, character are not automatically destroyed by default, but they will become at some point this year.
Because the characters remain in the memory and because they are not properly destroyed, the above code leaks memory. The connection remains alive despite being unreachable and unused.
The simplest solution is to enable the new behaviour (workspace.PlayerCharacterDestroyBehavior
).
An alternative involves either:
Edit: grammar and phrasing.
how do i create a collision group. ur gonna have to dumb it down alot for me i aint that smart
Hey, don’t put yourself down, you are definitely smarter than you think.
The best place to handle character collisions is in a server script in ServerScriptService. That way it is possible to have event connections in place to call appropriate functions when a player joins and each time their character is spawned. Those functions can do the job of changing collision groups.
I revised the code I sent in the previous reply and added comments to explain what everything does. The script already creates the collision group called ‘Players’.
To understand collision groups I recommend watching ByteBlox’s tutorial: https://www.youtube.com/watch?v=L4iO-T59XJM.
Luau as a high-level language is very humanly readable, so I’d like you to read it line by line and follow the keywords as if you were reading an English text, for example:
"for every instance in character do … if instance is a base part, set its collision group to ‘Players’
I hope this helps!
local PhysicsService = game:GetService("PhysicsService")
local PlayerService = game:GetService("Players")
-- Register the collision group 'Players' if it doesn't exist yet
if not PhysicsService:IsCollisionGroupRegistered("Players") then
PhysicsService:RegisterCollisionGroup("Players")
end
-- Prevent members of the same collision group from colliding
-- with each other
PhysicsService:CollisionGroupSetCollidable("Players", "Players", false)
local function OnCharacterAdded(character)
-- Iterate the table of all instances in the character
for _,instance in character:GetDescendants() do
-- Set the collision group to 'Players' if an instance is
-- a base part
if instance:IsA("BasePart") then
instance.CollisionGroup = "Players"
end
end
-- Listen for any instances that could be added later,
-- such as new accessories
character.DescendantAdded:Connect(function(descendant)
-- Just like before, if the new descendant is a base part,
-- configure the collision group to 'Players'
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Players"
end
end)
end
-- A function to call for every player that joins
local function PlayerJoined(player)
-- When a character is added, call OnCharacterAdded()
-- In case a character already exists, call it too
if player.Character ~= nil then
OnCharacterAdded(player.Character)
end
player.CharacterAdded:Connect(OnCharacterAdded)
-- Optional if workspace.PlayerCharacterDestroyBehavior is disabled
-- To prevent any memory leaks, why not clear the whole character?
player.CharacterRemoving:Connect(function(character)
task.wait(30)
character:Destroy()
end)
end
-- Call PlayerJoined for every player in game and
-- all players that will join the game
for _,player in PlayerService:GetPlayers() do
PlayerJoined(player)
end
PlayerService.PlayerAdded:Connect(PlayerJoined)
It works. Thank you very much!
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.