I am trying to make a fall damage script without using the humanoid.StateChanged event so that fall damage can happen even when the player is ragdolled.
The script is the following:
task.spawn(function()
local function onHitGround(distance:number) -- the "damage" function is from a ModuleScript and the function is way too big to copy, but it isn't the issue (removing it makes the same thing happen)
local damage = distance - 5
local leftLeg, rightLeg, torso = Limbs["Left Leg"], Limbs["Right Leg"], Limbs.Torso
if leftLeg and not leftLeg:GetAttribute("Cut") then
if rightLeg and not rightLeg:GetAttribute("Cut") then
damage /= 2
Damage(true, damage, rightLeg, velocityDamageStats, nil, nil, nil, "Fall Damage")
end
Damage(true, damage, leftLeg, velocityDamageStats, nil, nil, nil, "Fall Damage")
else
if rightLeg and not rightLeg:GetAttribute("Cut") then
Damage(true, damage, rightLeg, velocityDamageStats, nil, nil, nil, "Fall Damage")
elseif torso then
Damage(true, damage, torso, velocityDamageStats, nil, nil, nil, "Fall Damage")
end
end
end
local last_Y = Torso.Position.Y -- last Y level of the torso from the previous loop
local falling_Y = last_Y -- the Y level of the torso at the moment it starts falling
local wasFalling = false -- to check if the character was falling during the previous loop
while humanoid.Health > 0 do
task.wait(1)
local current_Y = Limbs.Torso.Position.Y
local isFalling = (current_Y < last_Y) -- checks if the character is falling in the current loop
if isFalling and not wasFalling then -- checks if it is currently falling and was not falling before
falling_Y = current_Y
print("Falling")
elseif not isFalling and wasFalling then -- checks if it is currently not falling but was falling before
local dist = falling_Y - current_Y
if dist > 10 then
onHitGround(dist)
print("Fallen")
end
end
wasFalling = isFalling
last_Y = current_Y
end
end)
Theorically, “onHitGround” is supposed to be called only once until the character falls from 10 studs again, but for some reason is called 6 times instantaneously (and I know it’s instantaneous because I tested the script using “task.wait(1)” instead of “task.wait()” and the loop executed 6 times without yielding). The number of times “onHitGround” is called is always 6 times and never varies.
I’ve also noticed that “wasFalling” does not set to “false” even when I explicitely set it to “false”. It’s like I have to set “wasFalling” to false 6 times for it to finally register that the variable has been set to false.
I can’t find any cause of this issue. I don’t know if I’m missing anything. I’ve tried finding posts of people with a similar issue, but it seems like I’m the first that it has ever happened. I am genuinely confused about how this could happen.