Trying to get a Fall damage Script to work

I want to achieve a working Fall damage script, in which people take damage based on their velocity when they land.

I’ve looked at this article and I tried to make a script based on that knowledge, where the velocity is the same for an instance when you land. Well, I tried and it didn’t do anything and the output doesn’t show any error (probably a dumb mistake on my part).

Any help would be very much appreciated. :wink:

P.S. I’m not a scripter, just a builder learning to script.

The script that I have got so far:

local character = game:GetService("Players").LocalPlayer.Character
local humanoid = script.Parent:FindFirstChild("Humanoid")
local fallVelocity = character.HumanoidRootPart.Velocity.Y

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

	if new == Enum.HumanoidStateType.Landed then

		if fallVelocity >= 40 then

			humanoid.Health = humanoid.Health - fallVelocity*math.random(86,98)/math.random(98,112)

		end
	end
end)

Try to print out if this even works. Maybe your math way is just wrong. Try printing.

1 Like

You’re only assigning the fallVelocity variable once, it does not change throughout the script. Allow me to explain.

Since you’re declaring a variable and setting its value to the Y axis of the HumanoidRootPart’s velocity, it would then be set to that value, and the variable’s value becomes that throughout the entire script unless you change its value to set the current one. In that case, you should define the variable again when the Humanoid has landed.

humanoid.StateChanged:Connect(function(old, new)
    if new == Enum.HumanoidStateType.Landed then
        fallVelocity = character.HumanoidRootPart.Velocity.Y;
        if fallVelocity >= 40 then
            -- . . . 
        end
    end
end)

another thing is that, assuming that the humanoid root part was falling, the Y axis would be negative, and so, using that as the damage does nothing, so we have to invert it back into positive

if new == Enum.HumanoidStateType.Landed then
        fallVelocity = -character.HumanoidRootPart.Velocity.Y;
        if fallVelocity >= 40 then
            -- . . . 
        end

Finally, if you are receiving any errors about things like the Humanoid not existing, you should use :WaitForChild() on both the Humanoid and HumanoidRootPart, since there are some situations where both don’t load as fast.

Alternative of doing this

While you can do your own method, alternatively, what I like to do is:

local SECONDS_THRESHOLD = 5
local DAMAGE_PER_SECOND = 10

local lastFreefall

Humanoid.StateChanged:Connect(function (old, new)
    if new == Enum.HumanoidStateType.Freefalling then
        lastFreefall = tick()
    elseif old == Enum.HumanoidStateType.Freefalling and new == Enum.HumanoidStateType.Landed and lastFreefall then
        local currentTime = tick()
        if currentTime > lastFreefall + SECONDS_THRESHOLD then
            -- This may be the wrong calculation
            local refinedTime = currentTime - (lastFreefall + SECONDS_THRESHOLD)
            Humanoid:TakeDamage(refinedTime * DAMAGE_PER_SECOND)
        end
    end
end)
6 Likes

Sorry forgot to edit this, I’ve already noticed it before but it still doesn’t work, but thx for the quick reply :slight_smile:

2 Likes

Thank you so much for explaining detailed and putting effort and time into your response, gosh this was very fast. :sweat_smile:

2 Likes

Hi !
there is another way to do fall damage, with the height :

--variable--

local Player = game.Players.LocalPlayer
local Character = Player.Character
local Humanoid = Character:WaitForChild("Humanoid")
local Y
local YF
local YL

--variable--

--SetVariable/ApplyDamage--

Humanoid.StateChanged:Connect(function (oldState, newState)
	if newState == Enum.HumanoidStateType.Freefall then
		YF = Y
	end
end)

Humanoid.StateChanged:Connect(function (oldState, newState)
	if newState == Enum.HumanoidStateType.Landed then
		YL = Y
		if YF - YL > 30 then --MinEightForTakeDamage--
			Humanoid:TakeDamage(YF-YL) --ApplyDamage--
		end
	end
end)

----SetVariable/ApplyDamage--

--GetY--

while true do
	Y = Character:WaitForChild("HumanoidRootPart").Position.Y
	wait()
end

--GetY--
1 Like

Have a good day ! :grinning:
I hope this will help you ! :grin: