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.
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
2 Likes
Thank you so much for explaining detailed and putting effort and time into your response, gosh this was very fast.
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 !
I hope this will help you !