Help with collision groups

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    Changing the player’s collision group to “Player”.

  2. What is the issue? Include screenshots / videos if possible!
    Issue is the collision group of the player is not changing.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried to doPlayer.PlayerAdded but it did not trigger when I join, tried Thouched event but also did not work.

Code for Player.PlayerAdded method.

Player.PlayerAdded:connect(function(player)
	player.CharacterAdded:Connect(function(character)
		for i, object in ipairs(character:GetDescendants()) do
			if object:IsA("BasePart") then
				object.CollisionGroup = "Player"
			end
		end
	end)
end)

Code for Thouched method.

SpawnLocation.Thouched:Connect(function(ThouchedPart)
	local plr = ThouchedPart.Parent
	if plr then
		local character = plr.Character
		for i, object in ipairs(character:GetDescendants()) do
			if object:IsA("BasePart") then
				object.CollisionGroup = "Player"
			end
		end
	end
end)
3 Likes

If possible, I want it to be activated when a player joins the game rather than touching a part.

local Players = game:GetService("Players");

local function PlayerAdded(Player)
	local function CharacterAdded(Character)
		if not Player:HasAppearanceLoaded() then
			Player.CharacterAppearanceLoaded:Wait();
		end

		for _, Object in pairs(Character:GetDescendants()) do
			if Object:IsA("BasePart") then Object.CollisionGroup = "Player" end 
		end
	end

	local Character = Player.Character or Player.CharacterAdded:Wait(); 
	CharacterAdded(Character);
	Player.CharacterAdded:Connect(CharacterAdded);
end

for _, Player in pairs(Players:GetPlayers()) do
	PlayerAdded(Player);
end

Players.PlayerAdded:Connect(PlayerAdded);

So essentially in studio you’ll run into an issue where your character has the chance of loading in before the code is executed. To fix this you’d loop over the existing players, and then make the connection to PlayerAdded. Then your next issue comes from the Character itself, CharacterAdded is fired the instant the model is instantiated, so you’d want to wait for the parts to load before attempting to set their collision grouping; that can be achieved by just waiting for the appearance to load if it’s not, which is already shown in the code above.

1 Like


Think it did not work.

That’s very weird cus I ran the exact same code, and produced the expected result.
https://gyazo.com/7028e73885f53703d2dd5d17c2359c34
Are you making sure the script is set to context legacy/server, enabled, and parented to a server-based script context like ServerScriptService

It is not only the collision group, the remote event which once worked are now broken and I have no idea why.

Are you receiving any errors in your output console at all?


Nothing at all.

CollisionGroups require something known as PhysicsService, PhysicsService allows you to Register CollisionGroups and Manage their Properties

local PhysicsService = game:GetService("PhysicsService") -- Service

PhysicsService:RegisterCollisionGroup("Player") -- Creates CollisionGroup

from there, you are able to Manage its Properties, you can even make it so you cant Collide with anything, Its a common way for you to make Players not be able to touch each other.

Your Code is working, but you just need to create the CollisionGroup

Although it is required to alter the collision group behavior, it isn’t technically required to set a part’s collision group; and wouldn’t/shouldn’t be causing his current issue of the script not working (without a given error). However, yeah I should have clarified that prior.

Yes, You can stills set CollisionGroups without Issue, the Problem is that it wont do anything unless you properly set it up.

However like you said, not the issue

So out of curiosity, are you using any custom character loading logic i.e turning the “CharacterAutoLoad” property off or something similar? Also are you using the same script for both the remote logic and collision group logic?

I have done none of that, the character are still your character and the script is a server script responsible for starting the game, ending the game and player’s collision.

Can you send the full updated script so we can have a full context of the issue at hand, you can remove certain parts that have nothing to do with the problem if you want I just want to know your variables and scoping to see if I can spot any reason it may not work. To me it sounds like the script is either yielding, or off.

local ServStorage = game:GetService("ServerStorage")
local BindEvent = ServStorage:WaitForChild("Bindable event")
local GameOver = BindEvent:WaitForChild("Game over")
local RepStorage = game.ReplicatedStorage
local base = require(RepStorage.Base)
local enemy = require(RepStorage.Enemies)
local Pathway = workspace.CityScapes.Path
local map = workspace.CityScapes
local tower = RepStorage:WaitForChild("Towers")
local gameOver = false
local Player = game:GetService("Players")
local PhysicsService = game:GetService("PhysicsService")

local function PlayerAdded(player)
	local function CharacterAdded(Character)
		if not player:HasAppearanceLoaded() then
			player.CharacterAppearanceLoaded:Wait();
		end
		
		for _, Object in pairs(Character:GetDescendants()) do
			if Object:IsA("BasePart") then Object.CollisionGroup = "Player" end 
		end
	end

	local Character = player.Character or player.CharacterAdded:Wait(); 
	CharacterAdded(Character);
	player.CharacterAdded:Connect(CharacterAdded);
end

for _, player in pairs(Player:GetPlayers()) do
	PlayerAdded(player);
end

base.Setup(map, 100)
GameOver.Event:Connect(function()
	gameOver = true
end)

for wave=1,5 do
	if wave < 5 then
		enemy.Spawn("Speedster", 2*wave, map)
	elseif wave == 5 then
		enemy.Spawn("Final Boss", 1, map)
	end
	repeat
		task.wait(0.5)
	until #map.WaitingQueue:GetChildren() == 0 or gameOver == true
	if gameOver == true then
		for i, remEnemy in ipairs(map.WaitingQueue:GetDescendants()) do
			remEnemy:Destroy()
			task.wait()
		end
		break
	end
	task.wait(0.5)
end

Player.PlayerAdded:Connect(PlayerAdded)

Here is the entire script.

local ServStorage = game:GetService("ServerStorage")
--local BindEvent = ServStorage:WaitForChild("Bindable event")
--local GameOver = BindEvent:WaitForChild("Game over")
--local RepStorage = game.ReplicatedStorage
--local base = require(RepStorage.Base)
--local enemy = require(RepStorage.Enemies)
--local Pathway = workspace.CityScapes.Path
--local map = workspace.CityScapes
--local tower = RepStorage:WaitForChild("Towers")
local gameOver = false
local Player = game:GetService("Players")
local PhysicsService = game:GetService("PhysicsService")

local function PlayerAdded(player)
	local function CharacterAdded(Character)
		if not player:HasAppearanceLoaded() then
			player.CharacterAppearanceLoaded:Wait();
		end

		for _, Object in pairs(Character:GetDescendants()) do
			if Object:IsA("BasePart") then Object.CollisionGroup = "Player" end 
		end
	end

	local Character = player.Character or player.CharacterAdded:Wait(); 
	CharacterAdded(Character);
	player.CharacterAdded:Connect(CharacterAdded);
end

for _, player in pairs(Player:GetPlayers()) do
	PlayerAdded(player);
end

Player.PlayerAdded:Connect(PlayerAdded)
--base.Setup(map, 100)
--GameOver.Event:Connect(function()
--	gameOver = true
--end)

for wave=1,5 do
	if wave < 5 then
		--enemy.Spawn("Speedster", 2*wave, map)
	elseif wave == 5 then
		--enemy.Spawn("Final Boss", 1, map)
	end
	repeat
		task.wait(0.5)
	until gameOver == true
	if gameOver == true then
		--for i, remEnemy in ipairs(map.WaitingQueue:GetDescendants()) do
		--	remEnemy:Destroy()
		--	task.wait()
		--end
		break
	end
	task.wait(0.5)
end

I stripped it down to the bare minimum for what I needed and moved the Player.PlayerAdded:Connect
logic up, and the code executes perfectly fine.

Tested the code in a new place and worked just like it was expected, it is only that one singular place that it didn’t.

Did you test every aspect, the modules, etc. If so that seems a little silly, maybe try restarting studio and then making sure the .Enabled property of the script is on.

The modules works fine. Everything works finely except for the player’s collision. Also the script is enabled the whole time.

Restarted studio and sure enough it is still default.