Help me with a "Unragdoll" script

Hello there, i currently have a script to ragdoll a player when something happens, but i need a way to unragdoll them, can anyone help me please, here’s the script:

                local Descendants = Chr:GetDescendants()

				for i = 1, #Descendants do
					local Descendant = Descendants[i]
						
					if (Descendant:IsA("Motor6D")) then
						local Socket = Instance.new("BallSocketConstraint")
										
						local Attachment0 = Descendant.Parent:FindFirstChild(Descendant.Name .."Attachment") or Descendant.Parent:FindFirstChild(Descendant.Name .."RigAttachment")
						local Attachment1 = Descendant.Part0:FindFirstChild(Descendant.Name .."Attachment") or Descendant.Part0:FindFirstChild(Descendant.Name .."RigAttachment")
										
						if (Attachment0 and Attachment1) then
							Socket.Attachment0 = Attachment0
							Socket.Attachment1 = Attachment1
								
							Socket.Parent = Descendant.Parent
								
							Descendant:Destroy()
						end

Chr is the player’s character

Any help is appreciated :sweat:

2 Likes

I tried it! All it takes is to keep around the Motor6D (but disconnected) after you ragdoll it, then reconnect the Motor6Ds and erase the Sockets when you want to unragdoll.

Working example, put in a Script and join in Play Solo/hit F6
workspace.ChildAdded:Connect(function(Chr)
	if Chr:IsA("Model") then
		wait(3)
		
		-- data that needs to be kept around to restore the character later
		local restoreDescendant = {}
		local restoreSocket = {}
		local restorePart1 = {} 

		for _,Descendant in ipairs(Chr:GetDescendants()) do -- used ipairs - makes no difference, just looks nicer

			if (Descendant:IsA("Motor6D")) then
				local Socket = Instance.new("BallSocketConstraint")

				local Attachment0 = Descendant.Parent:FindFirstChild(Descendant.Name .."Attachment") or Descendant.Parent:FindFirstChild(Descendant.Name .."RigAttachment")
				local Attachment1 = Descendant.Part0:FindFirstChild(Descendant.Name .."Attachment") or Descendant.Part0:FindFirstChild(Descendant.Name .."RigAttachment")

				if (Attachment0 and Attachment1) then
					Socket.Attachment0 = Attachment0
					Socket.Attachment1 = Attachment1

					Socket.Parent = Descendant.Parent

					--Descendant:Destroy() -- don't do this!
					
					-- store everything so it can be reverted later
					table.insert(restoreDescendant, Descendant)
					table.insert(restoreSocket, Socket)
					table.insert(restorePart1, Descendant.Part1)

					Descendant.Part1 = nil -- disconnect the Motor6D
					-- so it stops keeping the character rigid
					
					-- you could probably also set Descendant.Parent = nil
					-- to stop the character from ragdolling twice at once
					-- but some scripts could be relying on the motor6Ds being there
					-- still putting it here
					Descendant.Parent = nil
				end
			end
		end
		
		wait(3)
		-- unragdoll by readding the Motor6Ds
		-- if there were no Motor6Ds, then this does nothing
		-- because the restore* tables would have nothing in them
		for i = 1, #restoreDescendant do
			local Descendant = restoreDescendant[i]
			local Socket = restoreSocket[i]
			local Part1 = restorePart1[i]
			Descendant.Part1 = Part1
			Descendant.Parent = Socket.Parent -- read the comment about .Parent
			Socket:Destroy()
		end
	end
end)

You probably don’t want to only unragdoll after 3 seconds (as is in the code above), so I’ve made it easier to use.

ModuleScript
-- ModuleScript

-- Ragdolls a Model that may be a Character
-- Returns a function that will restore the character
-- You will have to make the function stop the character from flying up by yourself,
-- I did not bother learning to do that (Humanoid:SetState()?)

local function ragdoll(wrapper, model) -- runs in a coroutine
	-- data that needs to be kept around to restore the character later
	local restoreDescendant = {}
	local restoreSocket = {}
	local restorePart1 = {} 

	for _,Descendant in ipairs(model:GetDescendants()) do
		if (Descendant:IsA("Motor6D")) then
			local Attachment0 = Descendant.Parent:FindFirstChild(Descendant.Name .."Attachment") or Descendant.Parent:FindFirstChild(Descendant.Name .."RigAttachment")
			local Attachment1 = Descendant.Part0:FindFirstChild(Descendant.Name .."Attachment") or Descendant.Part0:FindFirstChild(Descendant.Name .."RigAttachment")
			
			if (Attachment0 and Attachment1) then
				-- setup ballsocket
				local Socket = Instance.new("BallSocketConstraint")
				Socket.Attachment0 = Attachment0
				Socket.Attachment1 = Attachment1
				Socket.Parent = Descendant.Parent
				
				-- store everything so it can be reverted later
				table.insert(restoreDescendant, Descendant)
				table.insert(restoreSocket, Socket)
				table.insert(restorePart1, Descendant.Part1)
				
				-- deactivate the Motor6D
				Descendant.Part1 = nil -- disconnect the Motor6D so it stops being rigid
				Descendant.Parent = nil -- remove the Motor6D so this function won't work on a character twice
			end
		end
	end
	
	-- return a function that continues this function, and waits until it is called
	coroutine.yield(wrapper)
	
	-- unragdoll by readding the Motor6Ds
	-- if there were no Motor6Ds, then this does nothing
	-- because the restore* tables would have nothing in them
	for i = 1, #restoreDescendant do
		local Descendant = restoreDescendant[i]
		local Socket = restoreSocket[i]
		local Part1 = restorePart1[i]
		Descendant.Part1 = Part1
		Descendant.Parent = Socket.Parent -- read the comment about .Parent
		Socket:Destroy()
	end
end

return function(model)
	local wrapper = coroutine.wrap(ragdoll)
	return wrapper(wrapper, model)
end
Script example
local ragdoll = require(workspace.ModuleScript)

-- ragdoll all characters that spawn and restore them after 3 seconds
workspace.ChildAdded:Connect(function(child)
	wait()
	local restore = ragdoll(child) -- does not check whether it is a character
	wait(3)
	restore()
end)

Require the ModuleScript (example in the script) to get a function that ragdolls a character.
The function returns a function, keep it around.
Call the function at any time to unragdoll the character.

2 Likes

I decided to implement this module into my combat system and encountered an error. When making the “player” characters ragdoll, it insta kills the player. Doesnt happen with npcs though.