I need help with a drowning script

Ah yes ur right, but with ur idea, the script would just skipt the for loop

Ahah, yeah - you got a point there. I didn’t consider adding a wait() in there. Thanks!

0skarian, the drowning does not happen after 30 seconds. The player started drowning immediately and I would like help to make the player drown after 30 seconds.

Yeah, we we’re discussing that. Use this new code instead:

for i = 1, 30 do
     if not Swimming then return end
     wait(1)
end

while Swimming do
	Humanoid:TakeDamage(5)
    wait(1)
end

I forgot to add a wait() command inside of the for loop. Apologies for the complications.

Thanks. Tell me when you finish discussing it.

This is how I would script this: I would make a variable time with value of 0, then I would do, while swimming add a second to the variable time. If time reaches 30sec, then start killing him

We already did. Using the provided piece of code should do the trick for once.

Thanks it works but, what do you mean by doing the trick once?

U are right, it doest the trick but what if player breathes? For loop doesnt work anymore and while loop is active

What you can do is essentially record the time instead of a true/false boolean like so:

local Character = script.Parent
local Humanoid = Character.Humanoid
local Swimming = false

Humanoid.StateChanged:Connect(function (oldState, newState)
	if newState == Enum.HumanoidStateType.Swimming then
		print("Swim")
		Swimming = tick()
	elseif oldState == Enum.HumanoidStateType.Swimming and newState ~= Enum.HumanoidStateType.Jumping then
		print("No swim")
		Swimming = false
	elseif oldState ~= Enum.HumanoidStateType.Swimming and oldState ~= newState then
		print("No swim")
		Swimming = false
	end
	
	while Swimming do
		wait()
		if tick() - Swimming > 30 then
			Humanoid:TakeDamage(5)
			wait(1) -- Or you can use a time capture again, that way its actually 1 second.
		end
	end
end)

What you may want to do for the breathing aspect is measure the height of the head in comparison to the water - or check if the part is within the Region3 of water zones.

7 Likes

That was just a clarification that it should work. Don’t worry about it.

No, that wouldn’t happen. If the player gets out the water while the for loop is still running, it will call return, ending the function and not allowing the while loop to run.

Not needed for any more variables (unless you add the little last drown effect I stated - this is only for fluidity when running), essentially when you use an IF statement your checking if something exists or is false:

local false_arg = false
local nil_arg = nil
local true_arg = true
local obj_arg = tick()

if false_arg then return end -- As its false.
if nil_arg then return end -- As nothing exists

if true_arg then return end -- As its true.
if obj_arg then return end -- As something exists in that memory pointer.

Checking if an object exists is great especially when using datastore :smile:

1 Like

Why does the character not heal after drowning?

What do you mean by that? If the player steps out the water before dying, Roblox’s default “Health” script should slowly heal the player.

You could use tick() to check if 30 seconds have passed to deal damage after that time has passed.

The roblox “Health” script is not healing the character but it usually does.

I have made an example for you in a localscript of how I would do this. Currently I do not think that subtracting health through a local script replicates to the server actually happens, which means if you want a multiplayer compatible script, this has to be done server side.

I use Humanoid:GetState() which returns the current state of the humanoid to see if you are still swimming, if you are not swimming the timer in the water resets and will continue from 30 if you are back into the water again.

The localscript example:

repeat wait() until game.Players.LocalPlayer.Character

local PS = game:GetService("Players")
local LP = PS.LocalPlayer
local Character = LP.Character
local Humanoid = Character:WaitForChild("Humanoid")
local Drowning = false

local DrownCount = 0

function HumanoidSwam(Old, State)
	if State == Enum.HumanoidStateType.Swimming then
		if Drowning == false then
			Drowning = true
			local StartTick = tick()
		
			DrownCount = 30
			while DrownCount > 0 do
				DrownCount = DrownCount - 1
				print(DrownCount)
				if Humanoid:GetState() ~= Enum.HumanoidStateType.Swimming then
					Drowning = false
					return
				end
				wait(1)
			end
		
			if DrownCount == 0 then
				while Humanoid:GetState() == Enum.HumanoidStateType.Swimming do
					Humanoid:TakeDamage(5)
					wait(5)
				end
			end
			Drowning = false
		end
	end
end

Humanoid.StateChanged:Connect(HumanoidSwam)

Did this help?

2 Likes

Nvm. I put it in the wrong type of script.

I am doing this for a multiplayer game. I do not know if this would work in one.