Disable Player Collissions Script?

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).

image

An alternative involves either:

  • manual tracking/storing and disconnecting of the connection (maids or janitors are noticably helpful);
  • manual destroying of the whole old character after a new one is spawned.

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 :skull:

Hey, don’t put yourself down, you are definitely smarter than you think. :smile:

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!

Script
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.