I created a fall damage script that hasn’t failed me once and is used on the client, but is there any more efficent ways to check?
while true do
local params = RaycastParams.new()
params.FilterDescendantsInstances = {Character}
local r = workspace:Raycast(Root.Position, Vector3.new(0, -4, 0), params)
if not r then
Falling.Value = true
else
Falling.Value = false
end
task.wait()
end
since I’m using a loop. I can’t just detect the humanoid states such as falling and landed because you ragdoll when you fall and so if you were to fall, hit something, ragdoll, then fall again while stunned (ragdolled,) then it wouldn’t do extra damage. That was the only problem using statetypes. the method I use now works all the time no matter what state the humanoid is in. I just fear that this loop might hinder performance a bit.
I personally opt for a different approach, whenever a character lands on the ground their humanoid state briefly changes to “landed”. When this happens I just check the AssemblyLinearVelocity of their HumanoidRootPart (which stays the same while the character’s humanoid has just landed) and deal damage if it’s high enough.
like this:
Connection = Humanoid.StateChanged:Connect(function(OldState, NewState)
if NewState == Enum.HumanoidStateType.Landed then
local YVelocity = HRP.AssemblyLinearVelocity.Y
if YVelocity <= -100 then
local Damage = (math.abs(YVelocity) - 100) * 2
if Damage >= 50 then
Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
Ragdoll:FireServer()
task.delay(5, function()
Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end)
end
FallDamageEvent:FireServer(Damage)
end
end
end)
Your approach is good as well, just up to preference!!
This is my first time ever on making a fall damage script. So, it might have a few bugs it but with my few minutes of testing it hasn’t have much issue so far
Fall Detection script(Local)
-- Note this script is in StarterCharacterScripts
local FallDamageEvent = game.ReplicatedStorage.FallDamageEvent
local startTime = 0
local character = script.Parent
local humanoid : Humanoid = character:FindFirstChild("Humanoid")
local jumping = false
local isStanding = true
local falling = false
local jumpBuffer = .2
local damageRange = 1 -- The ammount of time in which the player was in the air to initiate fall damage to begin
local deathRange = 10 -- If the player greater or equal to the range the player will automatically die
local baseFallDamge = 2 -- The ammount of health
local damageMultiplier = 2 -- The ammount to increase
local increaseDuration = 0.5 -- The ammount of time passed to increase the damage
local function fallDamageCalculation()
print("Calc")
local curr = tick()
local sum = curr - startTime
print(sum)
local function getDamageResult(t,timePassed)
local result = baseFallDamge
for i = 0,timePassed do
result = result * damageMultiplier
print(result)
end
return result
end
if sum > deathRange then
FallDamageEvent:FireServer(99999999999999)
else
if sum > damageRange then
local airTimeExtra = math.floor(math.abs(sum) / increaseDuration) - damageRange
print(airTimeExtra, "Time")
local damage = getDamageResult(sum,airTimeExtra)
FallDamageEvent:FireServer(damage)
else
return
end
end
end
humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
if humanoid.FloorMaterial == Enum.Material.Air and humanoid.Sit ~= true and humanoid.PlatformStand ~= true then
print("Air")
startTime = tick()
isStanding = false
task.delay(.4,function()
if humanoid.FloorMaterial == Enum.Material.Air then
falling = true
end
end)
else
if falling then
print("Falling")
fallDamageCalculation()
else
end
isStanding = true
startTime = 0
falling = false
jumping = false
end
end)
game['UserInputService'].InputBegan:Connect(function(input,gproc)
if not gproc then
if input.KeyCode == Enum.KeyCode.Space then
if jumping == false then
jumping = true
task.delay(jumpBuffer,function()
jumping = false
if humanoid.FloorMaterial == Enum.Material.Air then
falling = true
else
startTime = 0
end
end)
end
end
end
end)
Fall Damage script(Server)
game.ReplicatedStorage.FallDamageEvent.OnServerEvent:Connect(function(player,damage)
local humanoid : Humanoid = player.Character:FindFirstChild("Humanoid")
humanoid:TakeDamage(damage)
end)
Anyways hope this works or helps you find a solution. Happy Coding & good luck!