Why can't I create a ragdoll rig on R15 when the character spawns?

FINAL UPDATE: 2024-03-01


Thank you!

  • @hkep for the tool fix idea,
  • @223WinardKnot1 for giving me the idea to load the character after the respawn time,
  • @DayumBroOkay & @223WinardKnot1 for the idea of setting the Players Character to the clone when the player dies,
  • @Xeau for restructuring my connections script, this was very helpful and taught me some new things about coding.

Ragdoll Idea

  • When a character is added; build the players ragdoll joints,
  • Ragdoll the player if the ragdoll attribute is true,
  • When a player dies/respawns, create a clone of the player,
  • Ragdoll the clone, and change the characters camera to the clones head,
  • Destroy the host body, before the player can respawn,
  • When the player respawns, repeat everything above.

Issue 1

  • The player won’t respawn on death/character removed.

Issue 2

  • When using an R15 RigType, the ragdoll does not build correctly when the character is created. (meaning when the character spawns)

What I mean by the ragdoll doesn’t build correctly is, the BallSocketJoints attachments are empty for 0, and 1.

image ←

Issue 3

  • It constantly prints image when the character is removed/dies.

Solution 1

This is the marked solution;

Solution 2

Solution 3

How I deal with this, is by setting the users Player Character as nil.

Note about a tool issue

Note

I’m not adding in my tool solution as it’s a case-by-case situation, and I don’t believe the way I wrote the code was practical. I will however, explain what my issue was, and link the solution that best worked for me.

Tool Issue

  • The player would not get back up after being killed in a ragdoll state,
  • If someone was ragdolled by a player who died, they wouldn’t be unragdolled.

Tool Solution

Trigger a BindableEvent, that would hold the players stunned… and unstun them when required.



I hope this can help others with their ragdoll systems so we can have more compatible systems that can work with both R6, and R15.

5 Likes

Are you deleting the players humanoid? I believe that is the issue.

2 Likes

The entire player is destroyed when the player dies;
image
I’ve had the system like this before, and never had this issue before as the player would at least respawn.

Which issue are you addressing?

1 Like

Deleting the Character is what the problem is, you can set up a event for when the character is destroyed.

local Player = game.Players["Player"]

Player.CharacterRemoving:Connect(function()
	task.wait(3) -- waits 3 seconds before respawning
	Player:LoadCharacter()
end)
1 Like

This sadly does not work, as it doesn’t register that the players character was removed. Any other ideas?

--[[Made by Just2Terrify]]
--[[Players Character Added]]
game.Players.PlayerAdded:Connect(function(plr)
	local Protocol = require(game.ServerScriptService.Server_J2T_Control_Center.Modules.Functions)
	plr.CharacterAdded:Connect(function(Char)
		spawn(function() Protocol.Functions["Ragdoll Rig Builder"].Function(plr,Char) end)
	end)	
end)

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(Char)
		spawn(function()
			Char.Humanoid.Died:Connect(function()
				local Protocol = require(game.ServerScriptService.Server_J2T_Control_Center.Modules.Functions)
				Protocol.Functions["Death Ragdoll"].Function(plr,Char)
			end)
		end)
	end)
end)

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterRemoving:Connect(function(char)
		task.delay(game.Players.RespawnTime,function() --[[It has to run off the RespawnTime]]
			plr:LoadCharacter()
		end)
	end)
end)
1 Like

make characterremoving a signal, I guess.

2 Likes

When Destroying the CharClone you should do player:LoadCharacter() and you should probably set the players character to CharClone

1 Like

@BrAlMeSo_Mc & @223WinardKnot1
I’ve created a solution for this problem, and it does work! Instead of waiting for the character to be removed, just check whenever a child, or a decendant in this instance has been removed, and if the item is a model and is found in the Players Countainer.

game.Workspace.DescendantRemoving:Connect(function(Item)
	spawn(function()
		if Item:IsA("Model") and game.Players:FindFirstChild(Item.Name) then
			warn(Item.Name.." has been destroyed, attempting to respawn the player.")
			task.delay(game.Players.RespawnTime,function()
				if not game.Workspace:FindFirstChild(game.Players:FindFirstChild(Item.Name).Name) then
					game.Players[Item.Name]:LoadCharacter();warn("RESPAWNED PLAYER")
				elseif game.Workspace:FindFirstChild(game.Players:FindFirstChild(Item.Name).Name) then
					warn("PLAYER IS ALREADY SPAWNED")
				end
			end)
		end
	end)
end)
1 Like

Glad you fixed your problem, feel free to ask anymore questions!

2 Likes

I have solved the issue I responded with, please disregard this message

I would advise against this, as in a game typically speaking workspace has a lot of instances being added and removed from it. This might solve your problem, but is it really the most efficient way of doing so? Let’s take a look. You’re creating a ragdoll system, and your method of doing so is also pretty complicated.
My advice to you would be to change your code in the “Script” section you attached to this. I have gone through and modified the code to the best of my ability with coherent annotations. I hope you find this helpful!

--[[Made by Just2Terrify]]
--[[Players Character Added]]
local Protocol = require(game.ServerScriptService.Server_J2T_Control_Center.Modules.Functions) --This should only be required once, instead of each time a player is added. Module scripts only need to be required once.
local RESPAWN_DELAY = 3 --Set whatever your respawn duration preference is here
local CharacterAddedConnections = {} --This will be a table of all the connections we are using, not properly disconnecting your connections will lead to memory issues later down the road.
local CharacterDiedConnections = {}
game:GetService("Players").PlayerAdded:Connect(function(Player)
	local CharacterAddedCheck
	CharacterAddedCheck = Player.CharacterAdded:Connect(function(Character) --//Characters can spawn over and over, meaning we will be making a unique connection every time the player respawns. So, we will disconnect any previous death connections made.
		if CharacterDiedConnections[Player.Name] then
			if typeof(CharacterDiedConnections[Player.Name]) == "RBXScriptConnection" then
				CharacterDiedConnections[Player.Name]:Disconnect()--//Always disconnect connections that could lead to memory consumption!!
			end
			CharacterDiedConnections[Player.Name] = nil
		end
		task.spawn(Protocol.Functions["Ragdoll Rig Builder"].Function,Player,Character)
		local Humanoid = Character:WaitForChild("Humanoid")
		local CharacterDeathCheck
		CharacterDeathCheck = Humanoid.Died:Connect(function() --//We make a new character death check connection every time the player respawns!
			task.spawn(Protocol.Functions["Death Ragdoll"].Function,Player,Character)
			task.wait(RESPAWN_DELAY)
			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
				Player:LoadCharacter()
			end
		end)
		CharacterDiedConnections[Player.Name] = CharacterDeathCheck
	end)	
	CharacterAddedConnections[Player.Name] = CharacterAddedCheck
end)

game.Players.PlayerRemoving:Connect(function(Player) --//When players are removing, it's important to remember to disconnect any connections we have made to conserve memory!!
	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()--//Always disconnect connections that could lead to memory consumption!!
		end
		CharacterAddedConnections[Player.Name] = nil
	end
	if CharacterDiedConnections[Player.Name] then
		if typeof(CharacterDiedConnections[Player.Name]) == "RBXScriptConnection" then
			CharacterDiedConnections[Player.Name]:Disconnect()--//Always disconnect connections that could lead to memory consumption!!
		end
		CharacterDiedConnections[Player.Name] = nil
	end
end)

5 Likes

I thank you for the input, I’d love to learn more about connections if you’d be willing to send me some sources to look at!

Regarding this, the ragdoll is not connecting at all. When I trigger the ragdoll, it doesn’t ragdoll, but instead kills the player immediately.

I simply replaced my code to match yours, and now the ragdoll doesn’t work at all. I’m unsure as to why this is happening.

This should have entirely fixed your issue. I downloaded the place you provided and changed the scripts accordingly. I tested it myself in studio.
Go to your “Functions” module script and paste this.

--[[Made by Just2Terrify]]
local Protocol = {}

Protocol.Ragdolls = {};

Protocol.Functions = {
	["Ragdoll Rig Builder"] = {
		Description = "Builds a ragdoll for each character that spawns.",
		Function = function(Player,Character)
			local Ragdoll = require(game.ServerScriptService.Server_J2T_Control_Center.Modules.Ragdolls)
			local Humanoid = Character:FindFirstChild("Humanoid")
			Ragdoll.Functions["Build Rig"].Function(Character)
			if not table.find(Protocol.Ragdolls,Player.Name) then
				Protocol.Ragdolls[Player] = Character:GetAttributeChangedSignal("Ragdoll"):Connect(function()
					if Character:GetAttribute("Ragdoll")  then
						Ragdoll.Functions["Activate Ragdoll"].Function(Player.Name,true,Enum.HumanoidStateType.Physics,true)
					elseif not Character:GetAttribute("Ragdoll") then
						Ragdoll.Functions["Activate Ragdoll"].Function(Player.Name,false,Enum.HumanoidStateType.GettingUp,true)
					end
				end)
			end
			warn(Character.Name.." Ragdoll Built, BreakJoints & Require Neck is false.")
			return
		end,
	},
	["Death Ragdoll"] = {
		Description = "Activates a death ragdoll.",
		Function = function(plr,Char)
			local Ragdoll = require(game.ServerScriptService.Server_J2T_Control_Center.Modules.Ragdolls);warn(plr.Name.." has died, the death ragdoll has been activated.");Ragdoll.Functions["Activate Ragdoll"].Function(plr.Name,true,Enum.HumanoidStateType.Physics,false)
			return
		end,
	},
}

return Protocol

1 Like

You can fix this by not removing the humanoid.

1 Like

I believe the issue is that the script is running so fast; that the functions script can’t find the humanoid. I tried putting a WaitForChild, and a FindFirstChild on line 13, but it still didn’t work.

--[[Made by Just2Terrify]]
local Protocol = {}

Protocol.Ragdolls = {};

Protocol.Functions = {
	["Ragdoll Rig Builder"] = {
		Description = "Builds a ragdoll for each character that spawns.",
		Function = function(plr,Char)
			local Ragdoll = require(game.ServerScriptService.Server_J2T_Control_Center.Modules.Ragdolls);local Hum = Char:FindFirstChild("Humanoid")
			Ragdoll.Functions["Build Rig"].Function(Char)
			if not table.find(Protocol.Ragdolls,plr.Name) then
				Protocol.Ragdolls[plr] = game.Workspace[plr.Name]:GetAttributeChangedSignal("Ragdoll"):Connect(function()
					if game.Workspace[plr.Name]:GetAttribute("Ragdoll") == true then
						Ragdoll.Functions["Activate Ragdoll"].Function(plr.Name,true,Enum.HumanoidStateType.Physics,true)
					elseif game.Workspace[plr.Name]:GetAttribute("Ragdoll") == false then
						Ragdoll.Functions["Activate Ragdoll"].Function(plr.Name,false,Enum.HumanoidStateType.GettingUp,true)
					end
				end)
			end
			warn(Char.Name.." Ragdoll Built, BreakJoints & Require Neck is false.")
			return
		end,
	},
	["Death Ragdoll"] = {
		Description = "Activates a death ragdoll.",
		Function = function(plr,Char)
			local Ragdoll = require(game.ServerScriptService.Server_J2T_Control_Center.Modules.Ragdolls);warn(plr.Name.." has died, the death ragdoll has been activated.");Ragdoll.Functions["Activate Ragdoll"].Function(plr.Name,true,Enum.HumanoidStateType.Physics,false)
			return
		end,
	},
}

return Protocol

image

1 Like

See my edit I made here^ This should hopefully have resolved the issue.

2 Likes

Hey, I have a suggestion that might fix the warning you are getting in the output. Before you destroy the old character set the players character property to the new ragdoll clone. You can do this like so:

Player2Ragdoll.Character = CharClone

2 Likes

Sadly, it still has not. The ragdoll still does not activate, and i’m unsure as to why. It says the death ragdoll was activated when the ragdoll toggle is triggered.
Current place file with your suggested updates. (139.9 KB)

Don’t delete the old player, just make it fully transparent (set walkspeed and jumpheight to 0), spawn in the ragdoll, and set the ragdoll to be the target of the camera. Wait five seconds, and then call :LoadCharacter()

Or better yet, just replace the Motor6D joints in the player with ball and socket joints on death? This eliminates the need with an extra ragdoll player, and you can just wait five seconds and respawn the player as normal, and you can just replace the ball and socket joints with Motor6D joints to unragdoll the player.

2 Likes

The reason I replace the players ragdoll with a clone is so there’s a ragdoll to show, and the player can be respawned immediately.