Fall damage in ragdoll state

In a few words, I don’t know what do I need to do, so fall damage works while in ragdoll state.
I am using humanoid.FreeFalling event for my fall damage. It’s saving the last position of the character and then it subtracts the new height from the old height. And for ragdoll, I am using Enum.HumanoidStateType.Physics.

The problem:

How I want it to work:

I don’t need a script, I just need an explanation of how it could work. Anyways thanks for your time!

2 Likes

I’m assuming your problem is that the character doesn’t always take damage when it touches the ground. What if you rayast towards the ground constantly and checking for collisions that way?

2 Likes

It would cause performance issues on the server. But raycasting when the humanoid is falling is a good idea. I think Humanoid’s property FloorMaterial could help with detecting when the humanoid is falling. I will try out this solution later.

1 Like

Raycasting has great performance. I raycasted at 600 times per second without any issues with a low end laptop that I have. Floor material can work, however I don’t know if it will always register at the right time.

1 Like

I am currently working on the same problem lol.
I’ve tried using floormaterial and it works except floormaterial wont change while the player is ragdolled and it will wait until they get up from ragdoll to damage them.
However so far I found that using floor material is a good idea to detect when the player starts falling. If floormaterial = air then start waiting until they land. The only issue is detecting when they land.

I have not tried this yet but maybe putting a touched event on every limb and waiting for a result? You’d also have to filter out players, and parts with nocollide off. But it might work.
This is my code though if it helps.

hum:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
	if hum.FloorMaterial == Enum.Material.Air and not fallwaiting then
		fallwaiting = true
		playerHeight = char.HumanoidRootPart.Position.Y
		local oldvel
		print("w")
		repeat
			oldvel = char.HumanoidRootPart.AssemblyLinearVelocity.Y
			wait(.1)
		until hum.FloorMaterial ~= Enum.Material.Air or -- insert touched event trigger variable here
		print("finished")
		
		local fallheight = playerHeight - char.HumanoidRootPart.Position.Y
		fallwaiting = false

		if fallheight - minheight >= 1 then
			local dmg = (fallheight - minheight)*dmgperstud
			if dmg >= ragdolldmg then
				if dmg >= injurydmg then
					falldmg(dmg,true,true)
				else
					falldmg(dmg,false,true)
				end
				falldmg(dmg,false,true)
			else
				falldmg(dmg,false,false)
			end 
		end
	end
end)

I also added until hum.FloorMaterial ~= Enum.Material.Air or so that if the touched event somehow fails worse case they will still take fall damage it will just wait until they are unragdolled.

Have you tried using Humanoid.StateChanged (roblox.com) to detect when a player’s falling/lands?

Humanoid.StateChanged:Connect(function(OldState, NewState)
    if OldState == Enum.HumanoidStateType.Freefall and NewState == Enum.HumanoidStateType.Landed then
        -- What to do when the player lands after free falling
    end
end)
1 Like

as someone experiencing the same issue and running print tests.
the ragdoll / physics humanoid state makes it so the landed state doesn’t happen.

Also following what I previously said I realized how dumb the touched idea was as if u were falling and hit and slid against a wall as u fell you would take dmg.

I did this change to the code I posted and it works for me.
repeat until the floor material changes or the assemblylinearvelocity goes up.
I also made sure to raycast so it doesn’t accidently detect if the assemblylinearvelocity goes up from something like lag or a feature in your game that would bring a player up whilst falling.

until hum.FloorMaterial ~= Enum.Material.Air or char.HumanoidRootPart.AssemblyLinearVelocity.Y > oldvel and playerHeight > char.HumanoidRootPart.Position.Y + 2 and workspace:Raycast(char.HumanoidRootPart.Position,Vector3.new(0,-5,0))

There are some instances where it may not work depending on the game but this is a base idea for what could be done. I suggest tweaking the code for your game specifically.

1 Like

I didn’t know that I could find a solution from the toolbox. Here’s the result

And the script behind it

task.spawn(function()
	local fallTime = 0

	while true do
		if character ~= player.Character then break end

		local x = task.wait()

		if character:FindFirstChild("HumanoidRootPart") then
			if character.HumanoidRootPart.Velocity.Y <= -10 then
				fallTime = fallTime + x
			end

			if character.HumanoidRootPart.Velocity.Y > -10 then
				if fallTime >= 0.4 then
					local velocity = fallTime * 50 -- you can play with it until you like
					-- fall damage script
				end

				fallTime = 0
			end
		end
	end
end)

I had to kill my PC with 8 player test server, and the script activity wasn’t higher than 0.4%, so you don’t need to worry about the performance

2 Likes

This is a good solution but shouldn’t fall damage be scaled with height and distance rather than fall time? Laggy players or players who tab freeze would ultimately have increased fall time and take more fall dmg.