Player:LoadCharacter(targetCFrame, withholdCharacter)


#1

Currently if you call :LoadCharacter(), it creates a character and instantly moves it to <0, 100, 0>. If there are spawn locations, it then waits a bit and moves your character to a target spawn location. The most annoying side effect of the waiting is that if you try to move the character on characteradded, it gets re-positioned to where the game thinks it should be a couple split-seconds later. This makes creating custom spawn systems very annoying as you have to wait an arbitrary amount of time before you move the character to where you want them to spawn.

Something else that’s also impossible to do with current functionality is prepare the character for spawning before actually parenting it to the workspace (e.g. equipping armor to it before it spawns into the world). You could parent it to nil as soon as it’s added to the workspace, but due to latency, people would see the unprepared character spawn in at one of the spawns for a split second before the parent change to nil replicated to them. Additionally, say your character preparation takes 1/10th of a second. Because the PlayerGui is cleared when the character is loaded, you immediately lose your transition/loading screen when you load the character and you can see the character being prepared for that 1/10th of a second which is really ugly. A feature resolving these issues is essential for FilteringEnabled games in which the client must communicate and prepare alongside the server (i.e. the server needs to tell the client its loadout and replicate the loadout models to everyone which takes a while due to latency)

The solution:
Player:LoadCharacter(targetCFrame, withholdCharacter)

When targetCFrame is nil, the current spawn system is used. If it is not nil, regardless of what team the player is on, the spawns that are available, etc, the character will immediately be sent to the targetCFrame without going to the default-picked location in between.

When withholdCharacter is nil, LoadCharacter will behave as it does now and immediately set the character of the player to the loaded character and clear the PlayerGui / delete and re-add the backpack. If set to true, the character will be parented to nil, will load the character’s appearance (i.e. when a character is withheld their hats and body packages are still loaded onto the character parented to nil so that if you need to modify them during preparation you can), will not clear the PlayerGui / Backpack (so that custom loading screens don’t go away when the new character is being prepared), and the created character won’t be set as the character of the player (that shouldn’t be done until it’s done being prepared)

Returns the newly created character, even with empty parameters.


#2

I think that your suggested method would be great. However, have you ever tried having just one spawn and teleporting the player to your custom spawn once they collide with the single spawn. You could also base all your GUI transition off of that interaction if you have the GUI respawn thingy turned off.


#3

I already have a custom spawn system that works – I just had to use a really roundabout way to make it when I shouldn’t have. I can’t turn the GUI respawn thing turned off because I need some (most) of them to reset on respawn and I don’t want to have to loop through each item and delete it manually each time they respawn.


#4

For some reason .CharacterAdded is fired late when the player first joins on a slower connection. I set the character’s parent to nil on characteradded first thing, and every time I join the game, it’s slow when I first load in. It’s really weird – for some reason the loading screen is set to transparent (even though I can still see the ROBLOX symbol + #instances) and I see my character for a good 0.3 seconds (guesstimate – though, it’s much longer than a split second. It’s enough time for gravity to act on the character and cause it to fall a couple of studs) before it’s parented to nil. It’d really be nice if we could create characters and not instantly parent them to the workspace.


#5

The fact that it’s not already like this is what makes Roblox games feel like theyre being held together with popsicle sticks and glue.


#6

Please make this happen. Whenever players spawn in my game their screen obnoxiously flashes because they’re being created at somewhere ROBLOX thinks they should be and then I’m moving them to their proper spawn location for my game.


#7

THAT’S A THING!?

I had no idea why my spawning system wouldn’t work so I had it spam your position to be somewhere for 1000ms before releasing you. Did the job but felt so wrong.


#8

I’m fully in support of this.

As a Roblox developer, it is currently too hard to implement a custom spawn system. As @EchoReaper pointed out, if you go to move a character immediately after it loads, some obscure systems on the Roblox end of things move it back. This forces me to have to wait some vague amount of time before moving the character to the position I want, which is both unexpected behavior and quite hacky. The expected behavior is that once the character loads in, its position is not changed. CharacterLoaded implies that the character has already been loaded, not ALMOST done loading.

Here’s an example with a bare-bones custom spawn system.
SpawnBug.rbxl (14.4 KB)

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

local RESPAWN_TIME=0
local RAND=Random.new()
local Spawns=Workspace.Spawns:GetChildren()

Players.PlayerAdded:connect(function(Player)
	Player.CharacterAdded:connect(function(Character)
		Character.Humanoid.Died:connect(function()
			wait(RESPAWN_TIME)
			Player:LoadCharacter()
		end)
		
		local Spawn=Spawns[RAND:NextInteger(1,#Spawns)]
		--wait(3)
		Character:MoveTo(Spawn.Position)
	end)
	
	Player:LoadCharacter()
end)

If you uncomment the wait(3), you’ll notice that the character is successfully moved to a random spawn point. However, when commented, the spawn system completely breaks because of this obscure Roblox behavior. I shouldn’t have to work around these odd behaviors with loading characters to simply do what I want with the character after it is done loading.