Fall system can be improved?

Hello!

My english is not fluent, IF you don’t understand something i will try to explain.

I found out a tutorial how to make a fall system.
And here is the video: ROBLOX STUDIO | How to make Fall Damage [Customizable] - YouTube

Here is the code i made:

local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character


local Humanoid = Character:FindFirstChildWhichIsA("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")

local Damage1, Damage2, Damage3 = Instance.new("Sound", HumanoidRootPart), Instance.new("Sound", HumanoidRootPart), Instance.new("Sound", HumanoidRootPart)

Damage1.Name = "HurtFallDamage1"
Damage2.Name = "HurtFallDamage2"
Damage3.Name = "HurtFallDamage3"


Damage1.SoundId = "rbxassetid://12139943365"
Damage2.SoundId = "rbxassetid://12139945775"
Damage3.SoundId = "rbxassetid://12139947091"
Damage1.Volume = 1
Damage2.Volume = 1
Damage3.Volume = 1

local RandomDamage = {
	Damage1,
	Damage2,
	Damage3
}

Humanoid.StateChanged:Connect(function(OldState, NewState)
	if NewState == Enum.HumanoidStateType.Landed then
		local Height = -HumanoidRootPart.Velocity.Y
		if Height >= 100 then
			local Damage = (Height / 15) * 2.5
			Humanoid:TakeDamage(Damage)
			RandomDamage[Random.new():NextInteger(1,3)]:Play()
		end
	end
end)

How can i improve it?
Or it is good?

Everything looks great. But if you want a popular game another way to improve it is add effects like dirt reflecting off of the ground or other materials. Also gui showing and displaying how much damage was taken.

2 Likes

Hey!

Thanks for the suggestion, i will try make that.

~DarkGames

1 Like

2 things:
-Health does not replicate, you should be firing a remote event whenever someone takes fall damage so that the server can damage the humanoid.
-From my experience, the character’s velocity property is not very precise and sometimes falling from the same height could deal different fall damages, so the best option would be calculating how much time the character spent on freefall state.

2 Likes

Hello!

I know it was half a month to response.

So… how i can use a Remote Event to the humanoid?
I tried a few times, but i didn’t found a solution or maybe help about how to replicate Humanoid Health.

Can you explain me how to do it?

~DarkGames.

First, you need to store the Remote event can be accessed by client and server, replicated storage would be the best. Name it whatever you want, I’ll refer to it as FallDamage

On server sided script you write (put the script into ServerScriptService):

local FallDamageRemote = game:GetService("ReplicatedStorage").FallDamage

FallDamageRemote.OnServerEvent:Connect(function(player, damageAmount) 
--[[first param is always player
    you can add more params like I did with damage amount]]

   local char = player.Character
   if not char then return end
   local humanoid = char:FindFirstChildWhichIsA("Humanoid")
   humanoid:TakeDamage(damageAmount)
end)

and to fire the remote you write this on the client side:

local FallDamageRemote = game:GetService("ReplicatedStorage").FallDamage

FallDamageRemote:Fire(10) --does the function inside the script in server, damaging the player by the amount specified which is 10

Also be careful with Remote Events, anyone can fire them. Meaning that if exploiters wanted they could fire this event however they wanted, but as I get the player humanoid on server, it makes it impossible to damage other players than themselves.

If you don’t want to make them damage themselves then you can add more safety checks (such as checking player humanoidState and stuff on the server)

Thanks a lot for your time.

And one thing, if i should put the State on the server.

Should i wrote a code like this?

Server Script:

local HumanoidFallDamage = game:GetService("ReplicatedStorage").HumanoidFallDamage

HumanoidFallDamage.OnServerEvent:Connect(function(plr, humanoid)
      humanoid.StateChanged:Connect(function(OldState, NewState)
          --Code here.
    end)
end)

And the other script, that is local, should change to: “StarterCharacterScripts” to: “StarterGui”?

  1. You don’t need to change the local script location, and it is better to keep it at StarterCharacterScripts

  2. If you wanna check the state you should use humanoid:GetState(), also do not pass humanoid as a parameter, as exploiters can pass other players humanoids

  3. Every time you do a connection (:Connect) it uses memory, it also does everything in the code many times if you do it multiple times. As such you should not try to generate a connection every time you wanna check something.

  4. If you wanna switch the code to server side, you could just make the whole script on server side

Example of server sided code: (Credit to realism mod for the code)

-- Variables
local damageHeight = 14 -- The height at which the player will start getting damaged at
local lethalHeight = 26 -- The height at which the player will get killed

game:GetService("Players").PlayerAdded:Connect(function (plr)
	plr.CharacterAdded:Connect(function (char)
		
		local root = char:WaitForChild("HumanoidRootPart")
		local humanoid = char:WaitForChild("Humanoid")
		
		if humanoid and root then
			
			local headHeight
			
			wait(3) -- Prevent the player from dying on spawn
			humanoid.FreeFalling:Connect(function (state)
				if state then
					headHeight = root.Position.Y
				elseif not state and headHeight ~= nil then
					pcall(function ()
						
						local fell = headHeight - root.Position.Y
						
						if fell >= lethalHeight then
							humanoid.Health = 0
						elseif fell >= damageHeight then
							humanoid.Health = humanoid.Health - math.floor(fell)
						end
					end)
				end
			end)
		end
	end)
end)
1 Like

Thanks for the suggestion, i will try something on the server side, thanks a lot.

~DarkGames.