Why doesn't this fall damage script work half the time?

I haven’t tested this out of studio, but I think if I did it would probably have the same effect. Why does the landed state not work half the time for this script I made? Is there any problem with it?

local lastYPos = {}
function connectFallDamage(Char)
	
	local Humanoid = Char:FindFirstChild("Humanoid")
	local InAir = false
	
	Humanoid.StateChanged:Connect(function(old, new)
		if new == Enum.HumanoidStateType.Freefall then
			if lastYPos[Char] then return end
			local Root = Char:FindFirstChild("HumanoidRootPart")
			if Root then
				lastYPos[Char] = Root.Position.Y
				print(lastYPos[Char].." Falling")
			end
		elseif old == Enum.HumanoidStateType.Freefall and new == Enum.HumanoidStateType.Landed and lastYPos[Char] then
			local Root = Char:FindFirstChild("HumanoidRootPart")
			if Root then
				if lastYPos[Char] > Root.Position.Y then
					local Dmg = lastYPos[Char] - Root.Position.Y
					print(Dmg)
					Humanoid:TakeDamage(Dmg)
				else
				end
			end
			lastYPos[Char] = nil
		end
	end)
	
end

Before making this script I tested prints by just printing the state, and half the time it wouldn’t even print landed.

I don’t know much about scripting, but maybe because it’s build around free-fall and sometimes the character isn’t free falling.

free falling is always for me, but landed doesn’t always print.

Found the solution! Simplify the script:

script.Parent.Touched:connect(function(hit)
	if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
		hit.Parent.Humanoid.Health = 0
	end
end)

This script is easier to write, and will work all the time. Not just half the time.

That didn’t work before this is what I did.

Humanoid.StateChanged:Connect(function(State, NewState)
print(NewState)
end)

it won’t always print landed.

1 Like

don’t print fallen. Just use it regular. Printing messes it up i think. Also, make sure you use a script not a local script.

I don’t think printing is the issue with this. I tried without, and same problem.

1 Like

Wait, show me an image of your script.

I don’t want a different script, I want to know what the problem is with this script it would help me improve. Plus I’ve seen other scripts and most of them are similar to this.

1 Like

Show me an image of your script and i might find it.

It’s at the top of this thread.

1 Like

I mean the version i gave you.

script.Parent.Touched:connect(function(hit)
	if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
		hit.Parent.Humanoid.Health = 0
	end
end)

This is not a fall damage script, it’s a touched event that kills you on touch. It’s not efficient enough for what I’m aiming for, I’d have to paste that in every brick on the map for it to work.

1 Like

Oh you want a fall damage script wait lemme get one.

 hurtSoundId = "rbxassetid://147397876" -- Sound played if player takes fall damage.
minTime = 0.5 -- The minimum time a player has to fall in order to begin taking fall damage.
damagePerSec = 200

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

player = game.Players.LocalPlayer
character = player.Character or player.CharacterAdded:wait()
humanoid = character:WaitForChild("Humanoid")
torso = character:WaitForChild("Torso")
falling = false

hurtSound = Instance.new("Sound",torso)
hurtSound.SoundId = hurtSoundId

function onStateChanged(_,state)
	if state == Enum.HumanoidStateType.Jumping and not falling then
		falling = true
		local highestY = torso.Position.Y
		local start = tick()
		local peak = 0
		while falling do
			local y = torso.Position.Y
			if y > highestY then
				highestY = y
				peak = tick()
			end
			wait()
		end
		local damage = math.max(0,tick() - peak - minTime) * damagePerSec
		if damage > 5 then
			if humanoid.Health - damage > 0 then -- Only play the hurt sound if the damage isnt fatal.
				hurtSound.Volume = damage/humanoid.MaxHealth
				hurtSound:Play()
			end
			humanoid:TakeDamage(damage)
		end
	elseif state == Enum.HumanoidStateType.Landed then
		falling = false
	end
end

humanoid.StateChanged:connect(onStateChanged)

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

That should work.

I tested, and the same issue happens the script doesn’t always run the landed state. Plus now you have an ongoing loop waiting till the player lands.

1 Like

weird. Idk then your on your own with this. Developer.roblox.com might help tho.

The main thing I need help with is figuring out the problem, and resolving it. I want to know what the cause of the bug in my script is so I can solve it.

I do not mean to sound rude or harsh, just a friendly reminder that you should not attempt copy and paste free-model scripts from the Toolbox if you are inexperienced in this field (scripting). Developer.roblox.com is very vast, so it does not help anybody whatsoever. Again just a friendly reminder! :smiley:

4 Likes

Hi, first of all I think calculating fall damage versus fall time is not the best way to get fall damage!
Second, I think you can do this to know if the player is falling or not :

humanoid.StateChanged:Connect(function(oldState, newState)
	if newState == Enum.HumanoidStateType.Freefall then
		falling = true
	else
		falling = false
	end
end)

Or if you want you can check if the player is in air for know if is falling :

HumanoidGetPropertyChangedSignal:("FloorMaterial"):connect(function()
    if Humanoid.FloorMaterial == Enum.Material.Air then
        Falling = true
    else
        Falling = false
    end
end)