Player ragdoll while they're falling

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want the player to ragdoll while they’re falling and stop ragdolling once they land

  2. What is the issue? Include screenshots / videos if possible!
    My current script does not stop the ragdoll once they land

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

local Humanoid = script.Parent:WaitForChild('Humanoid')

local function HumanoidState(OldState, NewState)
	if (NewState == Enum.HumanoidStateType.Freefall) then
		for index,joint in pairs(script.Parent:GetDescendants()) do
			if joint:IsA('Motor6D') then
				local socket = Instance.new('BallSocketConstraint')
				local a1 = Instance.new('Attachment')
				local a2 = Instance.new('Attachment')
				a1.Parent = joint.Part0
				a2.Parent = joint.Part1
				socket.Parent = joint.Parent
				socket.Attachment0 = a1
				socket.Attachment1 = a2
				a1.CFrame = joint.C0
				a2.CFrame = joint.C1
				socket.LimitsEnabled = true
				socket.TwistLimitsEnabled = true
				joint:Destroy()
			end
		end
	end
end

Humanoid.StateChanged:Connect(HumanoidState)
8 Likes

Quick reply. Barely read code, you don’t have a loop constantly checking the playerstate, so it doesn’t check over and over if the person is still freefalling

1 Like

Alright thank you for the quick response, how would I stop it from looping though?

You don’t need a loop. With the same function, if the player’s new state is Landed, make the character in it’s original state.

1 Like

How would I revert it though, That was my first solution but I couldn’t figure out how to revert it

Edit: Sorry if I sounded rude.

Hope this helps:

local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local RootPart = Character:WaitForChild("HumanoidRootPart")
local RagDolled, CanGetUp = false, true
local RagDollParts = {}

Humanoid.StateChanged:Connect(function(OldState, NewState)
	if NewState == Enum.HumanoidStateType.Freefall and not RagDolled then
		RagDolled = true
		CanGetUp = false
		task.delay(1, function()
			CanGetUp = true
		end)
		Humanoid.AutoRotate = false
		Humanoid.PlatformStand = true
		for _, Object in ipairs(Character:GetDescendants()) do
			if Object:IsA("Motor6D") then
				local Socket = Instance.new("BallSocketConstraint")
				local A1 = Instance.new("Attachment")
				local A2 = Instance.new("Attachment")
				A1.Parent = Object.Part0
				A2.Parent = Object.Part1
				Socket.Parent = Object.Parent
				Socket.Attachment0 = A1
				Socket.Attachment1 = A2
				A1.CFrame = Object.C0
				A2.CFrame = Object.C1
				table.insert(RagDollParts, Socket)
				table.insert(RagDollParts, A1)
				table.insert(RagDollParts, A2)
				Socket.LimitsEnabled = true
				Socket.TwistLimitsEnabled = true
				Object.Enabled = false
			end
	
		end
	end
end)


while task.wait() do
	if not CanGetUp then
		continue
	end
	local CharacterParts = {}
	for i, Object in ipairs(Character:GetDescendants()) do
		if Object:IsA("BasePart") then
			table.insert(CharacterParts, Object)
		end
	end
	local RayParams = RaycastParams.new()
	RayParams.IgnoreWater = false
	RayParams.FilterDescendantsInstances = {CharacterParts}
	local Floor = workspace:Raycast(RootPart.Position, Vector3.new(0, -3, 0), RayParams)
	if RagDolled and Floor and Floor.Instance then
		Humanoid.AutoRotate = true
		Humanoid.PlatformStand = false
		for _, Object in ipairs(Character:GetDescendants()) do
			if Object:IsA("Motor6D") then
				Object.Enabled = true
			end
		end
		for i, Part in ipairs(RagDollParts) do
			Part:Destroy()
		end
		RagDolled = false
	end
end
10 Likes

So, we don’t need the code ‘Humanoid:ChangeState(Enum.HumanoidStateType.Physics)’? We will just use platformStand = true?

1 Like

this script works but it also ragdolls the player when the player jumps, any fix to that?

You could add a delay to check if the player is still falling after an amount of time, this ensures that the player won’t ragdoll from small heights and can only ragdoll after falling a certain amount of studs. You can change the stud amount by changing the variable value (local fallDelay = number), by default it’s 16 studs. Hope this helps:

local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local RootPart = Character:WaitForChild("HumanoidRootPart")
local RagDolled, CanGetUp = false, true
local RagDollParts = {}
local fallDelay = 16 -- Measured in studs

Humanoid.StateChanged:Connect(function(OldState, NewState)
	if NewState == Enum.HumanoidStateType.Freefall and not RagDolled then
       task.spawn(function()
			local humHeight = RootPart.Position.Y
			repeat
				task.wait()
			until RootPart.Position.Y <= humHeight - fallDelay
		RagDolled = true
		CanGetUp = false
		task.delay(1, function()
			CanGetUp = true
		end)
		Humanoid.AutoRotate = false
		Humanoid.PlatformStand = true
		for _, Object in ipairs(Character:GetDescendants()) do
			if Object:IsA("Motor6D") then
				local Socket = Instance.new("BallSocketConstraint")
				local A1 = Instance.new("Attachment")
				local A2 = Instance.new("Attachment")
				A1.Parent = Object.Part0
				A2.Parent = Object.Part1
				Socket.Parent = Object.Parent
				Socket.Attachment0 = A1
				Socket.Attachment1 = A2
				A1.CFrame = Object.C0
				A2.CFrame = Object.C1
				table.insert(RagDollParts, Socket)
				table.insert(RagDollParts, A1)
				table.insert(RagDollParts, A2)
				Socket.LimitsEnabled = true
				Socket.TwistLimitsEnabled = true
				Object.Enabled = false
			end
	
		end
		end)
		
	end
end)


while task.wait() do
	if not CanGetUp then
		continue
	end
	local CharacterParts = {}
	for i, Object in ipairs(Character:GetDescendants()) do
		if Object:IsA("BasePart") then
			table.insert(CharacterParts, Object)
		end
	end
	local RayParams = RaycastParams.new()
	RayParams.IgnoreWater = false
	RayParams.FilterDescendantsInstances = {CharacterParts}
	local Floor = workspace:Raycast(RootPart.Position, Vector3.new(0, -3, 0), RayParams)
	if RagDolled and Floor and Floor.Instance then
		Humanoid.AutoRotate = true
		Humanoid.PlatformStand = false
		for _, Object in ipairs(Character:GetDescendants()) do
			if Object:IsA("Motor6D") then
				Object.Enabled = true
			end
		end
		for i, Part in ipairs(RagDollParts) do
			Part:Destroy()
		end
		RagDolled = false
	end
end

i got a question, how will i detect if the body hits the floor?

This is late and you have probably figured it out. But you could check if the character has reached a certain velocity and ragdoll from there.