Is there a way to tell if a character has fully loaded?


Issue

For some reason, in R15; my RagdollSockets get removed when the character is respawned and I don’t know why. Is there some way to make sure the character has fully loaded before trying to build the rig?

Solutions tried

  • Player.CharacterAdded:Wait() does nothing. It still loads immediately… with the ragdollsockets not parenting correctly and becoming nil.
  • Player.CharacterAppearanceLoaded() does nothing as well, it still loads immediately with no Ragdoll Sockets attached.
    image

All coding was removed until I can test the efficiency of the code I’m using. Once I’ve completed my system, and I know it’s user friendly, I may release the whole system to the public.

Player.CharacterAppearanceLoaded

Just tried it, same issue. All the Ragdoll Sockets still don’t parent to the parts.

1 Like

You could consider repeatedly checking if the character.Parent is not nil until it’s fully loaded. However, in my experience, directly checking if the character is fully loaded has always been reliable. So, take my suggestion with a grain of salt.

2 Likes

I agree, it is usually trustable to use. It seems that the Attachments load that they’re together on the server… but not on the correct body… somehow. It shows that all the BallSocket Attachments are nil on the client, but says they’re all connected on the Server.

Could you give a more in-depth explanation of what occurs when a player resets/dies? Does the rig builder fail? Are checks not passing? Any errors?

Yeah, very easily actually. So, without me waiting for the character in workspace… the Attachments for the limbs won’t load to the client and everything will be blank. I’ve finally gotten past that… but now I have this issue;


Everything gets duplicated, meaning that somehow the character is loaded twice by roblox… not once.

All I did was add this line to the top of my Build Rig function; Character = game.Workspace:WaitForChild(Character.Name,30)

Are you sure you’re properly cleaning up the ragdoll joint instances upon death/reset?

Also… It’s a bit concerning that resorting to such measures is necessary for solving your problem. Using events like Player.CharacterAdded or Player.CharacterAppearanceLoaded would be better alternatives. However, if your current approach works for you, that’s fine. Just seems very hacky… no offense.

I absolutely agree, take a look at the Character Added function in the post. I was told that’s the most efficient way to keep stuff clean, and prevent lag.

image
This is now the mess I deal with… Lol

I’m sorta skimming through the code and I don’t see any part where you clean up the ragdoll joints. Please correct me if I’m mistaken.

Oh no, not the joints… the Character Added section;

local CharacterAddedConnections = {}; local CharacterDiedConnections = {}
game:GetService("Players").PlayerAdded:Connect(function(Player)
	local CharacterAddedCheck
	--Player.CharacterAdded:Wait()
	CharacterAddedCheck = Player.CharacterAdded:Connect(function(Character)
		if CharacterDiedConnections[Player.Name] then
			if typeof(CharacterDiedConnections[Player.Name]) == "RBXScriptConnection" then
				CharacterDiedConnections[Player.Name]:Disconnect()
			end
			CharacterDiedConnections[Player.Name] = nil
		end
		--Player.CharacterAdded:Wait()
		task.spawn(Protocol.Functions["Humanoid Properties Check"].Function,Player);task.spawn(Protocol.Functions["Blind Check"].Function,Player);
		task.spawn(Protocol.Functions["In Jail Check"].Function,Player);
		Protocol.Functions["Ragdoll Rig Builder"].Function(Player,Character)
		local Humanoid = Character:WaitForChild("Humanoid",30);local CharacterDeathCheck
		CharacterDeathCheck = Humanoid.Died:Connect(function()
			if CharacterDiedConnections[Player.Name] then
				if typeof(CharacterDiedConnections[Player.Name]) == "RBXScriptConnection" then
					CharacterDiedConnections[Player.Name]:Disconnect()
				end
				CharacterDiedConnections[Player.Name] = nil
			end
			task.spawn(Protocol.Functions["Death Ragdoll"].Function,Player,Character)
			if Player and Player:IsDescendantOf(game.Players) then else return end
			local Character = Player.Character 
			if typeof(Character) ~= "Instance" or not Character:IsDescendantOf(workspace) then
				task.delay(game.Players.RespawnTime,function()
					Player:LoadCharacter()
				end)
			end
		end)
		CharacterDiedConnections[Player.Name] = CharacterDeathCheck
	end)	
	CharacterAddedConnections[Player.Name] = CharacterAddedCheck
end)


--[[Player Removed]]
game.Players.PlayerRemoving:Connect(function(Player)
	if Player and Player.Name then else return end
	if CharacterAddedConnections[Player.Name] then
		if typeof(CharacterAddedConnections[Player.Name]) == "RBXScriptConnection" then
			CharacterAddedConnections[Player.Name]:Disconnect()
		end
		CharacterAddedConnections[Player.Name] = nil
	end
	if CharacterDiedConnections[Player.Name] then
		if typeof(CharacterDiedConnections[Player.Name]) == "RBXScriptConnection" then
			CharacterDiedConnections[Player.Name]:Disconnect()
		end
		CharacterDiedConnections[Player.Name] = nil
	end
end)

This ^

If you have any recommendations on how to clean up the Ragdoll Builder… I’m all ears.

Much of this code appears to be overly complex for no reason and could be simplified. I’ll work on rewriting the playeradded code and other parts to make things easier. I’ll share the revised version with you shortly.

1 Like

Thank you very much, I look forward to your response.

I have fixed the ragdoll to work by messing with how the build works; here’s the final product.

Essentially, you need to wait for the character in workspace… like so:
local Character = game.Workspace:WaitForChild(Player.Name,30) and use this to put, all Attachments, and BallSocketConstraints into.

Do you still need my version of the code, which doesn’t contain any functionality, just the basic structure?

I’m still willing to look at it and hear any recommendations you have.

Here’s a rough outline of how I might approach this. Keep in mind, this is just one way to do it and might not be the most efficient. If you notice any improvements or have questions, feel free to let me know. I’m still learning too, so take my suggestions with a grain of salt!

local Players = game:GetService("Players")

-- handle all character-related respawn functionality here
-- setting up ragdoll/checks/etc
local function onCharacterAdded(character)
	if not character then
		return
	end

	local player = Players:GetPlayerFromCharacter(character)
	local humanoid = character:FindFirstChildOfClass("Humanoid") or character:WaitForChild("Humanoid")

	-- protocol / functions - humanoid property check
	-- jail check
	-- rig builder
	warn('set up rig :D')

	humanoid.Died:Connect(function()
		-- spawn death ragdoll

		-- remove useless player if statement

		task.delay(Players.RespawnTime, function()
			player:LoadCharacter()
			warn('yipee!!')
		end)
	end)
end

-- cleaning up character-related functionality
local function onCharacterRemoving(character)
	warn('cleanup character related functionality here - ragdoll and stuff')
	-- clean up any connections or other data related to this character if you want
end

-- https://create.roblox.com/docs/reference/engine/classes/Player#CharacterAppearanceLoaded
local function onPlayerAddedAsync(player)
	player.CharacterAppearanceLoaded:Connect(onCharacterAdded)

	player.CharacterRemoving:Connect(function(character)
		onCharacterRemoving(character)
	end)
end

Players.PlayerAdded:Connect(onPlayerAddedAsync)

Players.PlayerRemoving:Connect(function(player)
	-- possibly disconnect all connections to the player, a connections table would make sense here.
end)

for _, player in ipairs(Players:GetPlayers()) do
	onPlayerAddedAsync(player)
end

Screenshot:

1 Like

I made a mistake in the Players.Removing connection. We shouldn’t try to destroy the player (Done automatically if I remember correctly). Apologies for the confusion! I remember doing something similar in the past and it worked but yea sorry for the confusion!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.