Custom parent for player characters

As far as I know, if you call Player:LoadCharacter() or if the engine calls that automatically when Players.CharacterAutoLoads == true, the engine instantiates a new Model object with a name equal to the Player.Name and parents that to Workspace.

The problem is that, if I want to filter only player characters in a OverlapParams I have to manually filter out everything else which is kind of not scalable if I add something else to Workspace.

Additionally, if the Player.Name collides with some internal identifier used by some object in the Workspace, anything waiting or looking for that child might get the character instead of the correct object. For example, my game has a Debris object in Workspace to store all temporary object from spells. I do not want someone named Debris to join and ruin the system.

A good way to solve this would be to add an instance reference property in StarterPlayer called CharacterParent so we can have a designated folder in Workspace meant only for player characters.

Although you can manually reparent them with CharacterAdded then there might be race conditions or Something unexpectedly tried to set the parent errors and if they go to Workspace first, for even a bit, that could still interfere with unwanted ChildAdded or WaitForChild calls. A clean way would just be to have a built-in way to customize the parent used for Character objects.

7 Likes

I don’t think this one is a big issue. While the characters are sort of just there in the workspace, the player objects (that have direct references to their characters) are secluded in game.Players, so you can get the players from there, and just add their .Character to a table, which you can then use in OverlapParams. If done properly, it’s going to be scalable so that you don’t really have to bother with it again.

You did make a good point about the similar names though. This actually happened in Doors, where an account named “figureCamPos” could singlehandedly break the game because the game didn’t expect a character with that name. While you could ““TECHNICALLY”” work around that, it isn’t a scalable or overall wise idea.

So a separate place for characters is indeed a good idea in order to keep things organized in a game.
And while we’re at it, can we please have the GUI not tied to player character spawning? PLEASE.

3 Likes

Use CollectionService and assign a tag i.e. “PlayerCharacter” to the loaded character. Doing this allows you to get all of the instances that you tagged in a {instance1, instance2, ...} format with a simple function CollectionService:GetTagged(). Then plug that result into the params to update and you should be good to go. This way, you don’t have to filter anything, you are essentially just marking objects and then getting the marked objects.

You can refer to the documentation for more info: CollectionService

The Ui is not tied to player character respawning if you set the ResetOnSpawn property of a screenGui object to false. Research properly before slandering Roblox.

1 Like

It seems you have misunderstood me. I know about the ResetOnSpawn property, however, I was referring to the fact that upon joining, Roblox loads in the contents of the StarterGui only after the player’s character has loaded. If you test this out by setting CharacterAutoLoads to false in Players, the GUI will not load at all.

P.S. I was not slandering Roblox, I was proposing this exact suggestion above.

1 Like

the solution is literally make your own custom character system that creates their characters in a folder/model or something else

(btw code below is not a custom character system its just a few lines of code solution for your problem)

local players=game:GetService("Players")
local characters=Instance.new("Folder")
characters.Name="Characters"
characters.Parent=workspace

players.CharacterAutoLoads=false
	
players.PlayerAdded:Connect(function(plr)
	local char=players:CreateHumanoidModelFromUserId(plr.UserId)
	
	char.Name=plr.Name
	plr.Character=char
	char.Parent=characters
end)