Ragdoll doesn't trigger Landed state

This is sort off a duplicate but I haven’t gotten any actual answers on why ragdoll PlatformStanding doesn’t trigger Landed thus breaking my fall damage script.

humanoid.StateChanged:Connect(function(old: Enum.HumanoidStateType, new: Enum.HumanoidStateType) 
	if new == Enum.HumanoidStateType.Freefall then
		repeat 
			CounterF += 1
			task.wait()
			print(CounterF)
			if CounterF == 58 then
				ReplicatedStorage.ASEETSTST.E__VV["FfDDD--f--"]:FireServer({
					FallDamageRagdollPenatly = true -- Ragdolls the player.
				})
			end
		until humanoid:GetState() == Enum.HumanoidStateType.Landed or humanoid:GetState() == Enum.HumanoidStateType.Dead or humanoid.FloorMaterial ~= Enum.Material.Air -- Runs forever when player is ragdolled and still continues when they got up.
		if CounterF >= 45 then
			ReplicatedStorage.ASEETSTST.E__VV["FfDDD--f--"]:FireServer({
				FallDamageRagdollPenatly = false,
				Velocity = CounterF
			})
		end
		CounterF = 0
		print(CounterF)
	end
end)

The PlatformStanding state doesn’t transition into regular physics states like Running, Freefall, Landed, Jumping. Otherwise, PlatformStanding would immediately exit itself if the player jumped or hit the ground. This is also true for .Sit except you can exit out of that state by jumping.

Instead of checking for ground impact with .Landed, check with the player velocity (AssemblyLinearVelocity).

How would that achieve that exactly? Any examples?

I would check for the changes in the velocity repeatedly through a while loop and track the starting and stopping positions.

task.defer(function()
	local root: BasePart = workspace:WaitForChild("treebee63").PrimaryPart
	local fallStartingY
	
	local STATE = "NORMAL"
	
	while true do
		if STATE == "NORMAL" then
			if root.AssemblyLinearVelocity.Y < 0 then
				STATE = "FALLING"
				fallStartingY = root.Position.Y
			end
		elseif STATE == "FALLING" then
			if root.AssemblyLinearVelocity.Y >= 0 then
				STATE = "NORMAL"
				local height = fallStartingY and fallStartingY - root.Position.Y
				if height and height > 0 then
					print("user fell from a height of", fallStartingY - root.Position.Y)
				end
			end
		end
		
		task.wait()
	end
end)

Is there a way to detect if height has a reached a certain number? I tried rounding the number to the approximate and see if it is falling but sometimes it skips through the number.

if math.floor((fallStartingY and fallStartingY - root.Position.Y))) == 55 then
	print("Player should ragdoll during midair.")		
end

Use >= instead of ==

I assume you also want to trigger the ragdolling only once

local isRagdolling = false
if fallStartingY and fallStartingY - root.Position.Y >= 55 and not isRagdolling then
	isRagdolling = true -- set this to false when the player exits ragdoll
	print("Player should ragdoll during midair.")		
end

One more question, for some reason, when player gets ragdolled midair, they get damaged? Why? it seems to reset AssemblyLinearVelocity and set the STATE to NORMAL

Roblox’s physics checking is occasionally unreliable. It could be that going into the ragdoll state causes the root velocity to reset for whatever reason. To patch this, I recommend to add a cooldown from fall damage after transitioning to the ragdoll state.

local isRagdolling = false
local ragdollStartTime = 0
if fallStartingY and fallStartingY - root.Position.Y >= 55 and not isRagdolling then
	ragdollStartTime = tick()
	isRagdolling = true -- set this to false when the player exits ragdoll
	print("Player should ragdoll during midair.")		
end

-- code to deal fall damage
elseif STATE == "FALLING" then
	if root.AssemblyLinearVelocity.Y >= 0 and tick() - ragdollStartTime  > 1 then -- we don't trigger fall damage until 1 second has passed since the last ragdoll event
		STATE = "NORMAL"
		local height = fallStartingY and fallStartingY - root.Position.Y
		if height and height > 0 then
			print("user fell from a height of", fallStartingY - root.Position.Y)
		end
	end
end

Should this be in falling state or not? Since this is how my code is structed.

task.spawn(function()
	local isRagdolling = character.CharacterStats.Ragdolled.Value
	local ragdollStartTime = 0
	local fallStartingY
	local root:BasePart? = character.HumanoidRootPart
	local STATE = "NORMAL"

	while true do
		if STATE == "NORMAL" then
			if root.AssemblyLinearVelocity.Y < 0 then
				LOCKEDRAGDOLL = false
				STATE = "FALLING"
				fallStartingY = root.Position.Y
			end
			if fallStartingY and fallStartingY - root.Position.Y >= 55 and not isRagdolling then
				ragdollStartTime = tick()
				isRagdolling = true 
				print("Player should ragdoll during midair.")		
			end
		elseif STATE == "FALLING" then
			if root.AssemblyLinearVelocity.Y >= 0 and tick() - ragdollStartTime  > 1 then 
				STATE = "NORMAL"
				local height = fallStartingY and fallStartingY - root.Position.Y
				if height and height > 0 then
					print("user fell from a height of", fallStartingY - root.Position.Y)
				end
			end
		end
		task.wait()
	end
end)

If you want the player to be falling while in midair, it would make sense to put the check under the falling state and not the normal state.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.