Need Help For Oxygen system

I need help making an oxygen system. I am new to scripting and got this script out of another topic. I tried to make the player take damage when the oxygen is depleted but it isn’t working (sorry if this post is bad this is my first time)

3 Likes
function drowning()

local char = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()

local humanoid = char:WaitForChild("Humanoid")

humanoid:TakeDamage(25)

end

game.Players.PlayerAdded:Connect(function(player)

local increaseRate = 3

local decreseRate = 2

local oxygen = Instance.new("IntValue", player)

oxygen.Value = 1000

oxygen.Name = "OxygenValue"

wait(3)

while wait() do

local char = player.Character or player.CharacterAdded:Wait()

local castRay = Ray.new(char.Head.Position, Vector3.new(0,-10,0))

local whiteList = {char}

local hit, hitposition = workspace:FindPartOnRayWithIgnoreList(castRay, whiteList)

local underwater = false

if not hit or not hit:IsA("Terrain") then

local castRay2 = Ray.new(char.Head.Position + Vector3.new(0,1000,0), Vector3.new(0,-1000,0))

local hit2, hit2position = workspace:FindPartOnRayWithIgnoreList(castRay2, whiteList)

if hit2 and hit2:IsA("Terrain") then

underwater = true

if oxygen.Value == 0 then

repeat drowning() until underwater == false

end

end

end

if underwater == false then

oxygen.Value = math.clamp(oxygen.Value + increaseRate, 0, 1000)

else

oxygen.Value = math.clamp(oxygen.Value - decreseRate, 0, 1000)

end

end

end)

Any repies will be appreciated :smiley:

There’s a couple red flags that I see here. Just to name a few:

  • Health is NOT replicated. (The drown script for taking damage should be on the server)
  • If your script is on the server already, you cannot define the player as game.Players.LocalPlayer
  • The ray method used in this example code is deprecated, use the newer workspace:Raycast() with the correct RaycastParams
  • Using wait() instead of task.wait()
  • Doing this under a while wait() loop

There’s some other misc stuff like how you should define the properties of an Instance before parenting it to a descendant of workspace. Why? Click here

Since you’re new to programming, none of this that I mentioned is going to be obvious to you. I pointed it out though just so you’re aware next time and can learn from this experience.

can you tell me how to fix this

nothing was obvious to me
I am really new (as i mentioned)

my script is already in server script service, so how do I define humanoid?

I don’t recommend posting here if you’re too new to scripting or if your code is not of your property.

If your script is a server-sided script you cannot use Players.LocalPlayer to define the local player, as you’re already using PlayerAdded event you can use its first parameter to declare these variables.

In the drowning function that is defined in the code you posted, you’d have to add a parameter for the player you want to deal damage to.

function Drowning(Player)
    local Character = Player.Character or Player.CharacterAdded:Wait()
    if Character then
        local Humanoid = Character:FindFirstChild("Humanoid")
        -- find out if they're under water or not, then damage them
    end
end

So then as @Sarchyx has stated, inside of your game.Players.PlayerAdded event, you can pass in the player for the drowning function easily.

1 Like

Can you just give me the script plz, Im still a kid I still dont understand.

@NoParameters can you please show me how to do this?

function drowning(player)
	local char = player.Character
	local humanoid = char:WaitForChild("Humanoid")
	humanoid:TakeDamage(25)
end

game.Players.PlayerAdded:Connect(function(player)
	local increaseRate = 3
	local decreseRate = 2
	local oxygen = Instance.new("IntValue", player)
	oxygen.Value = 1000
	oxygen.Name = "OxygenValue"
	wait(3)
	while wait() do
		local char = player.Character or player.CharacterAdded:Wait()
		local castRay = Ray.new(char.Head.Position, Vector3.new(0,-10,0))
		local whiteList = {char}
		local hit, hitposition = workspace:FindPartOnRayWithIgnoreList(castRay, whiteList)
		local underwater = false
		if not hit or not hit:IsA("Terrain") then
			local castRay2 = Ray.new(char.Head.Position + Vector3.new(0,1000,0), Vector3.new(0,-1000,0))
			local hit2, hit2position = workspace:FindPartOnRayWithIgnoreList(castRay2, whiteList)
			if hit2 and hit2:IsA("Terrain") then
				underwater = true
				if oxygen.Value == 0 then
					repeat drowning(player) until underwater == false
				end
			end
		end
		if underwater == false then
			oxygen.Value = math.clamp(oxygen.Value + increaseRate, 0, 1000)
		else
			oxygen.Value = math.clamp(oxygen.Value - decreseRate, 0, 1000)
		end
	end
end)

Copy and paste inside a server script, place it inside workspace or ServerScriptService folder.

When I die it doesnt reset the oxygen

You’ll need to add a Humanoid.Died event which is fired whenever a humanoid dies, and then reset the stamina.

https://developer.roblox.com/en-us/api-reference/event/Humanoid/Died

function drowning(player)
	local char = player.Character
	local humanoid = char:WaitForChild("Humanoid")
	humanoid:TakeDamage(25)
end

game.Players.PlayerAdded:Connect(function(player)
	local increaseRate = 3
	local decreseRate = 2
	local oxygen = Instance.new("IntValue", player)
	oxygen.Value = 1000
	oxygen.Name = "OxygenValue"
	wait(3)
	while wait() do
		local char = player.Character or player.CharacterAdded:Wait()
		local humanoid = char:WaitForChild("Humanoid")
		humanoid.Died:Connect(function()
			oxygen.Value = 1000
		end)
		local castRay = Ray.new(char.Head.Position, Vector3.new(0,-10,0))
		local whiteList = {char}
		local hit, hitposition = workspace:FindPartOnRayWithIgnoreList(castRay, whiteList)
		local underwater = false
		if not hit or not hit:IsA("Terrain") then
			local castRay2 = Ray.new(char.Head.Position + Vector3.new(0,1000,0), Vector3.new(0,-1000,0))
			local hit2, hit2position = workspace:FindPartOnRayWithIgnoreList(castRay2, whiteList)
			if hit2 and hit2:IsA("Terrain") then
				underwater = true
				if oxygen.Value == 0 then
					repeat drowning(player) until underwater == false
				end
			end
		end
		if underwater == false then
			oxygen.Value = math.clamp(oxygen.Value + increaseRate, 0, 1000)
		else
			oxygen.Value = math.clamp(oxygen.Value - decreseRate, 0, 1000)
		end
	end
end)

Like this.

function drowning(player)
	local char = player.Character
	local humanoid = char:WaitForChild("Humanoid")
	humanoid:TakeDamage(25)
end

game.Players.PlayerAdded:Connect(function(player)
	local increaseRate = 3
	local decreseRate = 2
	wait(3)
	while wait() do
		local char = player.Character or player.CharacterAdded:Wait()
		player.CharacterAdded:Connect(function(character)
			local oxygen = Instance.new("IntValue", player)
			oxygen.Value = 1000
			oxygen.Name = "OxygenValue"
		end)
		local castRay = Ray.new(char.Head.Position, Vector3.new(0,-10,0))
		local whiteList = {char}
		local hit, hitposition = workspace:FindPartOnRayWithIgnoreList(castRay, whiteList)
		local underwater = false
		if not hit or not hit:IsA("Terrain") then
			local castRay2 = Ray.new(char.Head.Position + Vector3.new(0,1000,0), Vector3.new(0,-1000,0))
			local hit2, hit2position = workspace:FindPartOnRayWithIgnoreList(castRay2, whiteList)
			if hit2 and hit2:IsA("Terrain") then
				underwater = true
				if oxygen.Value == 0 then
					repeat drowning(player) until underwater == false
				end
			end
		end
		if underwater == false then
			oxygen.Value = math.clamp(oxygen.Value + increaseRate, 0, 1000)
		else
			oxygen.Value = math.clamp(oxygen.Value - decreseRate, 0, 1000)
		end
	end
end)

I just realized in the script the player loses the IntValue instance named “Oxygen” when they die so resetting the value isn’t enough, you instead need to recreate the IntValue instance and parent it to the player each time they respawn.

1 Like

In the last script I found theat when I touch the seabed the oxygen goes up

That’s likely because the script thinks that the seabed isn’t underwater (for whatever reason), you could try extending the depth of the water below the seabed to fix that.

Thank you so much it actually worked!