Need Help with Temporary Ragdoll

So I’ve made (poorly put together) this code that does a basic ragdoll (without the parts moving) after jumping or freefall and gets back up again. I’m having trouble making it ragdoll normally (parts moving). The script below is what I made (its a local script in StarterPlayer\StarterCharacterScripts):

local UserInputService = game:GetService("UserInputService")
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
humanoid.StateChanged:Connect(function(oldState, newState)
   if newState == Enum.HumanoidStateType.Jumping or newState == Enum.HumanoidStateType.Freefall then 
   	wait(.2)
   	if humanoid:GetState() == Enum.HumanoidStateType.Freefall then
   		humanoid:ChangeState(Enum.HumanoidStateType.Physics)
   		wait(1)
   		humanoid:ChangeState(Enum.HumanoidStateType.Ragdoll)
   	end
   end
end)

I think this reply is very helpful but I don’t really know how to loop through all of the Character’s Motor6Ds and disable them, enable constraints and vice versa : Temporary Ragdoll? - #5 by dcampeon

This was my first try at scripting, go easy on me :p. I’m hoping the solution would help anyone looking to do similar stuff (ragdoll after getting attacked, getting hit by car etc.)

3 Likes

Begin code with these characters ``` and end the code with the same three characters this makes it easier to read your code.

1 Like

You can use a for loop to go through the character and automatically stop when it’s finished.

for _,v in pairs(character:GetDescendants()) do
	if v:IsA('Motor6D') then
		--Code
	end
end

The loop gets all of the character’s descendants with GetDescendants(), and then IsA() checks which of these descendants are Motor6Ds.

1 Like

I have something like

for _, v in pairs(character:GetDescendants()) do
				if v:IsA("Motor6D") then
					local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
					a0.CFrame = v.C0
					a1.CFrame = v.C1
					a0.Parent = v.Part0
					a1.Parent = v.Part1

					local b = Instance.new("BallSocketConstraint")
					b.Attachment0 = a0
					b.Attachment1 = a1
					b.Parent = v.Part0

					v:Destroy()
				end
			end

But I’m having trouble with doing the opposite like enabling motor 6Ds and disabling constraints.
Is it like this?:

for _, v in pairs(character:GetDescendants()) do
				if v:IsA("Motor6D") then
                    local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
					temp1=a0.CFrame
					temp2=a1.CFrame
					temp3=a0.Parent
					temp4=a1.Parent
					
					a0.CFrame = v.C0
					a1.CFrame = v.C1
					a0.Parent = v.Part0
					a1.Parent = v.Part1

					local b = Instance.new("BallSocketConstraint")
					temp5=b.Attachment0
					temp6=b.Attachment1
					temp7=b.Parent
					b.Attachment0 = a0
					b.Attachment1 = a1
					b.Parent = v.Part0

					v:Destroy()
					wait(20)
					b.Attachment0 = temp5
					b.Attachment1 = temp6
					b.Parent = temp7
					a0.CFrame =temp1
					a1.CFrame = temp2
					a0.Parent = temp3
					a1.Parent = temp4
				end
			end

After trying this, the character just falls down after jumping with no ragdoll and doesn’t get back up. The whole script would looks like this:

local UserInputService = game:GetService("UserInputService")
local character = script.Parent

local humanoid = character:WaitForChild("Humanoid")
humanoid.StateChanged:Connect(function(oldState, newState)
	if newState == Enum.HumanoidStateType.Jumping or newState == Enum.HumanoidStateType.Freefall then 
		wait(.2)
		if humanoid:GetState() == Enum.HumanoidStateType.Freefall then
			humanoid:ChangeState(Enum.HumanoidStateType.Physics)
			humanoid.BreakJointsOnDeath = false
			humanoid.RequiresNeck=false
			for _, v in pairs(character:GetDescendants()) do
				if v:IsA("Motor6D") then
                    local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
					temp1=a0.CFrame
					temp2=a1.CFrame
					temp3=a0.Parent
					temp4=a1.Parent

					a0.CFrame = v.C0
					a1.CFrame = v.C1
					a0.Parent = v.Part0
					a1.Parent = v.Part1

					local b = Instance.new("BallSocketConstraint")
					temp5=b.Attachment0
					temp6=b.Attachment1
					temp7=b.Parent
					b.Attachment0 = a0
					b.Attachment1 = a1
					b.Parent = v.Part0

					v:Destroy()
					wait(1)
					b.Attachment0 = temp5
					b.Attachment1 = temp6
					b.Parent = temp7
					a0.CFrame =temp1
					a1.CFrame = temp2
					a0.Parent = temp3
					a1.Parent = temp4
				end
			end
			wait(1)
			humanoid:ChangeState(Enum.HumanoidStateType.Ragdoll)
			
		end
	end
end)

You shouldn’t destroy the Motor6Ds. They have an enabled value, so you can simply set that value to false. And I would suggest you name the attachments and constraints so that you can get them when you need to. Once you wish to end the ragdoll, just remove the attachments and constraints with another for loop but instead of IsA() you would instead get them by name.

I’ve named the attachments and constraints “fakeMotor” and “fakeJoint” respectively.

for _,v in pairs(character:GetDescendants()) do
	if v:IsA('Motor6D') then
		v.Enabled = true
	end
	if v.Name == 'fakeMotor' then
		v:Destroy()
	end
	if v.Name == 'fakeJoint' then
		v:Destroy()
	end
end
1 Like

It works just as intended! Thank you so much! This has to be the easiest press R to ragdoll script available out there and it can be easily adapted anywhere!:

local UserInputService = game:GetService("UserInputService")
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
UserInputService.InputBegan:Connect(function(inputObject)
	if inputObject.KeyCode == Enum.KeyCode.R then
		humanoid.BreakJointsOnDeath = false
		humanoid.RequiresNeck=false
		humanoid:ChangeState(Enum.HumanoidStateType.Physics)
		for _, v in pairs(character:GetDescendants()) do
			if v:IsA("Motor6D") then
				local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
				a0.CFrame = v.C0
				a1.CFrame = v.C1
				a0.Parent = v.Part0
				a1.Parent = v.Part1
				local b = Instance.new("BallSocketConstraint")
				b.Attachment0 = a0
				b.Attachment1 = a1
				b.Parent = v.Part0
				v.Enabled = false
			end
		end
		wait(1)
		for _,v in pairs(character:GetDescendants()) do
			if v:IsA('Motor6D') then
				v.Enabled = true
			end
			if v.Name == 'BallSocketConstraint' then
				v:Destroy()
			end
			if v.Name == 'Attachment' then
				v:Destroy()
			end
		end
		wait(1)
		humanoid:ChangeState(Enum.HumanoidStateType.Ragdoll)	
	end
end)
2 Likes

I like the simplicity! Couple things…

I’d use Enum.HumanoidStateType.GettingUp to resume after ragdoll, vs. Enum.HumanoidStateType.Ragdoll
The transition looks smoother to me. Also, not sure why you’re waiting one second after enabling the motors again. Try it without that and with the ‘gettingup’ state, looks super smooth to me.

The server(other players) won’t see the ragdoll effect. So if you want to ‘fix’ that you’d need a remoteevent and server side script, but then the simplicity suffers. But I don’t think it wouldn’t add too much complexity to add that in.

1 Like

Here is the client/server version of your script:

For those who haven’t tried this script yet what it does is, player presses R, gets ragdolled for 5 seconds, then unragdolled.

The Localscript, put in character:

local RagdollServerEvent = game.ReplicatedStorage:WaitForChild("RagdollServer")
local RagdollClientEvent = game.ReplicatedStorage:WaitForChild("RagdollClient")
local UserInputService = game:GetService("UserInputService")
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")

UserInputService.InputBegan:Connect(function(inputObject, processed)
	if processed then return end --added this so you don't ragdoll when typing in chat
	if inputObject.KeyCode == Enum.KeyCode.R then
		humanoid.BreakJointsOnDeath = false
		humanoid.RequiresNeck=false
		humanoid:ChangeState(Enum.HumanoidStateType.Physics)
		RagdollServerEvent:FireServer(character)
		--wait(5)  this will be done on the server
	end	
end)

local function unragdoll()
	humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
	humanoid.BreakJointsOnDeath = true
	humanoid.RequiresNeck = true
end

RagdollClientEvent.OnClientEvent:Connect(unragdoll)

Server script, put where server scripts can run:

local RagdollServerEvent = Instance.new("RemoteEvent")
RagdollServerEvent.Name = "RagdollServer"
RagdollServerEvent.Parent = game.ReplicatedStorage
local RagdollClientEvent = Instance.new("RemoteEvent")
RagdollClientEvent.Name = "RagdollClient"
RagdollClientEvent.Parent = game.ReplicatedStorage

function tempragdoll(player,character)
	for _, v in pairs(character:GetDescendants()) do  --ragdoll
		if v:IsA("Motor6D") then
			local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
			a0.CFrame = v.C0
			a1.CFrame = v.C1
			a0.Parent = v.Part0
			a1.Parent = v.Part1
			local b = Instance.new("BallSocketConstraint")
			b.Attachment0 = a0
			b.Attachment1 = a1
			b.Parent = v.Part0
			v.Enabled = false
		end
	end
	wait(5)
	for _,v in pairs(character:GetDescendants()) do  --unragdoll
		if v:IsA('Motor6D') then
			v.Enabled = true
		end
		if v.Name == 'BallSocketConstraint' then
			v:Destroy()
		end
		if v.Name == 'Attachment' then
			v:Destroy()
		end
	end
	RagdollClientEvent:FireClient(player)
end



RagdollServerEvent.OnServerEvent:connect(tempragdoll)

I added a couple lines to undo the breakjoints and neck thing, not sure if that is needed. Also added ‘processed’ to the R key thing to prevent ragdoll from typing R in chats.

9 Likes

I didn’t think someone would even look at such a poor script of mine, let alone totally revamping it! Who would’ve thought my very first attempt at scripting would be this successful. And for all of it being done in one day! I’ll be sure to credit you folks in the upcoming community resource post. After that I hope people like me will never have difficulties with ragdoll scripts in general, as long as Motor6Ds, Attachments and ball socket Constraints exists. I can’t thank you guys enough. I hope you have a great day, I know I will.

4 Likes