I am helping to develop an event which has a large quantity of people moving at the same time. I made a collision filter, which changed the cancollide value if a player was in a group or owned a gamepass. I received the error that the player was a datamodel, or something related to that. I could only replicate it in the server where there was a lot of people joining. I need help asap, my code is down here:
local physics = game:GetService("PhysicsService")
local Players = game:GetService("Players")
local GamePassService = game:GetService('MarketplaceService')
local gamePassForcefield = game.Workspace.GroupDoorModel.GamePassDoor
local gamePassForceFields = "GamePass"
local hasGamePass = "gamePassPlayers"
local GamePassId = 6318668
physics:CreateCollisionGroup(gamePassForceFields)
physics:CreateCollisionGroup(hasGamePass)
physics:SetPartCollisionGroup(gamePassForcefield, gamePassForceFields)
physics:CollisionGroupSetCollidable(gamePassForceFields, hasGamePass, false)
local function setCollisionGroupRecursive(object, groupName)
if object:IsA("BasePart") then
physics:SetPartCollisionGroup(object, groupName)
end
for _, child in ipairs(object:GetChildren()) do
setCollisionGroupRecursive(child, groupName)
end
end
local function onCharacterAdded(character)
local player = game.Players:GetPlayerFromCharacter(character)
if GamePassService:UserOwnsGamePassAsync(player.userId, GamePassId) or player:GetRankInGroup(4837748) == 3 or player:GetRankInGroup(4837748) > 5 then
local collisionGroupName = hasGamePass
setCollisionGroupRecursive(character, collisionGroupName)
end
end
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
I do not care about optimization at this time, just getting it to work.
If I had to make a wild guess based on the vague error description, perhaps ‘player’ is returning nil (which could happen if GetPlayerFromCharacter is invoked when someone is leaving right after joining?). You may want to check if local player = game.Players:GetPlayerFromCharacter(character) returns nil and return if that’s the case. For more in-depth suggestion you’d need to supply the full error message.
N.B. GetDescendants() is essentially the recursive version of GetChildren()
A possible cause is that you only iterate through the Character’s children rather than all its descendants, so parts from accessories are left out. (Oops, replied to the wrong reply)
I sort of have a problem with my onCharacterAdded function, even after the character is reset, they do not get added to the collisionGroup. Is there a way to possibly assign a collision group right after a player buys the gamepass?
You could probably listen to the ProcessReceipt callback, although this page only lists it for developer products, I’m not entirely sure if it works the same for gamepasses.
Okay, I edited my script and used some pcall functions to make it work no matter what.
local physics = game:GetService("PhysicsService")
local Players = game:GetService("Players")
local GamePassService = game:GetService('MarketplaceService')
local gamePassForcefield = game.Workspace.GroupDoorModel.GamePassDoor
local gamePassForceFields = "GamePass"
local hasGamePass = "gamePassPlayers"
local GamePassId = 6318668
physics:CreateCollisionGroup(gamePassForceFields)
physics:CreateCollisionGroup(hasGamePass)
physics:SetPartCollisionGroup(gamePassForcefield, gamePassForceFields)
physics:CollisionGroupSetCollidable(gamePassForceFields, hasGamePass, false)
local function setCollisionGroupRecursive(object, groupName)
if object:IsA("BasePart") then
physics:SetPartCollisionGroup(object, groupName)
end
for _, child in ipairs(object:GetDescendants()) do
setCollisionGroupRecursive(child, groupName)
end
end
local function onCharacterAdded(character)
local player = game.Players:GetPlayerFromCharacter(character)
if player == nil then return end
if pcall(GamePassService:UserOwnsGamePassAsync(player.userId, GamePassId) or player:GetRankInGroup(4837748) == 3 or player:GetRankInGroup(4837748) > 5) then
local collisionGroupName = hasGamePass
setCollisionGroupRecursive(character, collisionGroupName)
end
end
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character)
end)
end
local function gamepassPurchaseFinished(player, gamePassId, wasPurchased)
if player == nil then return end
if player.Character:FindFirstChild("Humanoid") then
if gamePassId == 6318668 then
if wasPurchased == true then
local character = player.Character
local collisionGroupName = hasGamePass
pcall(setCollisionGroupRecursive(character, collisionGroupName))
end
end
end
end
GamePassService.PromptGamePassPurchaseFinished:Connect(gamepassPurchaseFinished)
Players.PlayerAdded:Connect(onPlayerAdded)
Unless I’m unaware of changes Roblox made to pcall, I imagine you need to write pcall(setCollisionGroupRecursive(character, collisionGroupName)) as pcall(setCollisionGroupRecursive,character,collisionGroupName) otherwise it’d be calling pcall with the return value of that function
I completely forgot that there was a function that recursively returned the children, I fixed that; thank you for the pcall syntax thing, I am new to using more advanced things such as that.