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
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.
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.