How to detect when a player is actually freefalling

I was making a simple ragdoll script which ragdolls a player when it is falling from a height.

Code-

local char = script.Parent
local hum = char.Humanoid
hum.BreakJointsOnDeath = false

hum.StateChanged:Connect(function(old, new)
	if new == Enum.HumanoidStateType.Freefall then
	for index, joint in pairs(char: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
		wait(3)
		game.Players:GetPlayerFromCharacter(char):LoadCharacter()
	end
end)

Everything seems to work except when I jump, it detects jumping as ragdoll. This isn’t something I want. I want to make a player ragdoll only if it’s falling from a height. Help is appreciated. Thanks!

I think you can use HumanoidStateType, this property can detect what the character is doing. After your character jumps, and when it falls down, the HumanoidStateType is Freefall
I don’t know if this can help you.

Yes, this and I also suggest adding a delay of a few seconds to avoid ragdolling immediately after jumping, so the player can land on their feet if the jump isn’t that high, unless you want the ragdoll to be immediate, then don’t add a delay and just use HumanoidStateType.

Sorry, but I don’t really understand what do you mean by “using HumanoidStateType”. I have used it in my script. Can you elaborate a little bit more? Sorry if this sounds dumb. @GGreenBBoy123 @aDemoness

You can try raycasting downwards.

Try getting the vector velocity of the character

You could try adding an attribute to the player called “IsFalling” (if you want to). So you could have the local script in character scripts like this

local char= game.Players.LocalPlayer.Character
char.Humanoid.FreeFalling:Connect(function(a)
	if a then print('falling') char:SetAttribute('IsFalling',true) end
end)
char.Humanoid.StateChanged:Connect(function(state)
	if state == Enum.HumanoidStateType.Landed and char:GetAttribute('IsFalling') then
       print('landed')
       char:SetAttribute('IsFalling',false) 
    end 
end)

The reason there’s an attribute is because free falling is kinda buggy. You enter it when you’re falling like normal. But it also activates as soon as you hit the ground for some reason. So there’s an attribute to act like a boolean.

Edit: I just figured out you dont need the attribute but i think its good to keep

try this. It should check the velocity of the HRP and ragdoll the character only when the Y velocity is high enough, which should only happen if the character is falling.

hum.StateChanged:Connect(function(old, new)
	if new == Enum.HumanoidStateType.Freefall then   
        if math.abs(char:WaitForChild("HumanoidRootPart").AssemblyLinearVelocity.Y) > 10 then
	        for index, joint in pairs(char:GetDescendants()) do
			-- code here
            end
	    end
    end
end

haven’t tested if the velocity needed is too low or high, so just change the 10 in the if statement accordingly if needed (formatting might be weird, I’m on phone)

1 Like

Example:

local freefalling = false
local time = tick()
if humanoid.FloorMaterial == Enum.Material.Air then
if time >= 5 then
freefalling = true
else
freefalling = false
end
end