Attempting to switch Humanoid State from Freefalling

When attempting to switch the active HumanoidState from FreeFalling to another state like Ragdoll or FallingDown whilst in the air, the humanoid’s state refuses to change.
I’ve attempted using Humanoid:ChangeState() and Humanoid:SetStateEnabled(), however, neither change the Humanoid’s State from FreeFalling.
My goal is to change the Humanoid’s State to FallingDown when the Humanoid has been in the air for more than a second

this code should works
detects airborne time for 1 seconds.

local AIRBORNE_TIME = 1 -- seconds
local isAirborne = false
local airborneStartTime = 0

humanoid.StateChanged:Connect(function(_, newState)

	-- When the player enters Freefall or Jumping
	if newState == Enum.HumanoidStateType.Freefall or newState == Enum.HumanoidStateType.Jumping then
		if not isAirborne then
			isAirborne = true
			airborneStartTime = tick() -- record time they became airborne

			-- Start check
			task.delay(AIRBORNE_TIME, function()
				-- Only trigger if still airborne after delay
				if isAirborne and humanoid:GetState() == Enum.HumanoidStateType.Freefall then
					print("Player airborne for 1 second!")
					--PUT YOUR CODE FOR RAGDOLL HERE
				end
			end)
		end

		-- When player lands
	elseif newState == Enum.HumanoidStateType.Landed then
		isAirborne = false
	end
end)

I should clarify some more about the situation I’m in.
My Ragdoll and fall damage scripts are completely separate. The ragdoll script checks for the FallingDown humanoid state so that way if the player gets flung by fast moving parts, it automatically ragdolls. That works completely fine.
However, the issue I’m having is that I am attempting to change the Humanoid state from Freefall to FallingDown in a completely separate script that handles stuff like fall damage. It’s easier for me to change the Humanoid State, because setting the Humanoid State to FallingDown allows Roblox’s humanoid code to handle stuff, like changing the Humanoid State after 3 seconds of being at a standstill to stand back up.
Because of this, I want to be able to switch from Freefall to FallingDown, however, changing the Humanoid State doesn’t work, at least when falling.
This is the code I am using to change the Humanoid State:

print("At Valid Velocty")
h:ChangeState(Enum.HumanoidStateType.FallingDown)
print(h:GetState())

Yet, it prints the following:

At Valid Velocty  -  Server - FallDamage:21
Enum.HumanoidStateType.Freefall  -  Server - FallDamage:23

Meaning it very clearly meets the condition to switch Humanoid States, but Roblox is refusing to change it from Freefall

Let me get this straight. You want to change the humanoid state to FallingDown after 1 second of being airborne? I think the most elegant solution is to create your own state handler instead of relying on Roblox’s built-in state system.

Yes. However, Roblox refuses to change the Humanoid State from Freefall

have you considered making your own state handler. it will make things much more easier

Roblox’s state handler is convenient for certain things, like when being hit by fast moving parts, that’s the only reason I’m using it for this situation

Humanoid | Documentation - Roblox Creator Hub ok i did some digging and i think you cannot set the “Falling Down” state manually using the ChangeState(). That state is controlled by the engine and only occurs through physics interactions, not through script-triggered state changes as the docs said.


there is no mention that you can use ChangeState() to alter the state for falling down

I was able to force FallingDown when the user is in the Running, Climbing, or Seated states. The only time I couldn’t was in the Freefalling state. Plus, other states mentioned on that page that can’t be set explicitly state Cannot be set with Humanoid:ChangeState(). (such as in StrafingNoPhysics)
image
It seems the only issue is with Freefall.
Anyways, I’ve found a really jank workaround of enabling then disabling PlatformStand in order to force the user out of the Freefall state. Thanks anyways!

Hey there! So I just tested it out, and it worked perfectly fine for me.

Script I used (LocalScript)
local timeUntilFall = 0.1

local function onCharacterAdded(character)
	local humanoid: Humanoid = character:WaitForChild("Humanoid")

	humanoid.StateChanged:Connect(function(old, new)
		warn(new)

		if new == Enum.HumanoidStateType.Freefall then
			task.delay(timeUntilFall, function()
				if humanoid:GetState() == Enum.HumanoidStateType.Freefall then
					warn(`Fell for {timeUntilFall} {timeUntilFall == 1 and "second" or "seconds"}; changing state`)
					--humanoid:SetStateEnabled(Enum.HumanoidStateType.Freefall, false)
					--humanoid:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, true)
					humanoid:ChangeState(Enum.HumanoidStateType.FallingDown)
				end
			end)
		end
	end)
end


game.Players.LocalPlayer.CharacterAdded:Connect(onCharacterAdded)

Btw @HeartIessDeviI I know you used AI for that script. Everything in it screams AI; that’s also why you flagged my post as “Off Topic.” AI is a great tool; just don’t deny it and claim it as your own. I appreciate your overall efforts, though.