My value is going negative super fastly

I am making an oxygen system (if you are touching the water your oxygen will drain), but the level isn′t going slow and steady (1 second = -1 value of the oxygen), but it′s going so super saiyan fast, it reached negative in 2 seconds.

We need to see the code responsible for draining oxygen to help you resolve the issue

4 Likes

I’ll do it tomorrow, can’t now, sorry!

add task.wait(0.1) and make sure the value is more than 0

local part = game.Workspace.woer

local ChildDescentHead = game.Players.LocalPlayer.Character.PrimaryPart

local function onTouch(ChildDescentHead)
	while part.Touched do
	wait(1)
	script.Parent.Value -=1
	end
end

local function onTouchEnded(ChildDescentHead)
script.Parent.Value = 45
end

part.Touched:Connect(onTouch)
part.TouchEnded:Connect(onTouchEnded)

A few issues

Touched is an event, not a property you can reference

You need a proper debounce system for this to work as right now there’s no debounce

However, since I assume you’re trying to make a zone using touched events, I recommend you use either Spatial queries or ZonePlus, to make a zone. You can use these to detect a player within every second to reduce the value. It’s finicky to make a zone via touched events

2 Likes

WaterOxygenTest.rbxl (47.0 KB)

image

local HeadList = {}

script.Parent.Touched:Connect(function(part)
	if part.Name == "Head" then
		local player = game.Players:GetPlayerFromCharacter(part.Parent)
		if player then
			if HeadList[player.UserId] == nil then
				HeadList[player.UserId] = part
			end
		end 
	end
end)

script.Parent.TouchEnded:Connect(function(part)
	if part.Name == "Head" then
		local player = game.Players:GetPlayerFromCharacter(part.Parent)
		if player then
			if HeadList[player.UserId] then
				HeadList[player.UserId] = nil
				part:SetAttribute("Oxygen",1)
			end
		end 
	end
end)

local secondsOfOxygen = 5
local elapsed = 0

while true do
	for _,head in pairs(HeadList) do
		local oxygen = head:GetAttribute("Oxygen") or 1
		oxygen = math.max(oxygen-((1/secondsOfOxygen)*elapsed),0)
		head:SetAttribute("Oxygen",oxygen)
	end
	elapsed = task.wait()
end

image
image

local player = game.Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local screenGui = playerGui:WaitForChild("OxygenScreenGui")
local backBar = screenGui:WaitForChild("OxygenBar")
local frontBar = backBar:WaitForChild("Level")

backBar.BackgroundColor3 = Color3.new(1,1,1)
frontBar.BackgroundColor3 = Color3.new(.2,.2,1)
local oxyLevel = 1

local module = {}

module.Reset = function()
	screenGui.Enabled = false
	frontBar.Size = UDim2.new(1,-4,1,-4)
	backBar.BackgroundColor3 = Color3.new(1,1,1)
	frontBar.BackgroundColor3 = Color3.new(.2,.2,1)
	oxyLevel = 1
end

module.Draw = function(level)
	screenGui.Enabled = true
	oxyLevel = level
	frontBar.Size = UDim2.new(level,-4,1,-4)
	local backColor = Color3.new()
	if level == 0 then
		frontBar.Visible = false
		backColor = Color3.new(1,0,0)
	else
		frontBar.Visible = true
		backColor = Color3.new(level,level,level)
	end
	backBar.BackgroundColor3 = backColor
	local frontColor = Color3.new()
	if level < .5 then
		frontColor = Color3.new(1,level*2,level*2)
	else
		local rg = 1-(((level-.5)/.5)*.8)
		frontColor = Color3.new(rg,rg,1)
	end
	frontBar.BackgroundColor3 = frontColor
end


return module

image

local character = script.Parent
local head = character:WaitForChild("Head")
local oxygenBarModule = require(character:WaitForChild("OxygenBarModule"))

oxygenBarModule.Reset()

head:GetAttributeChangedSignal("Oxygen"):Connect(function()
	local oxygenLevel = head:GetAttribute("Oxygen")
	
	if oxygenLevel < 1 then
		oxygenBarModule.Draw(oxygenLevel)
	else
		oxygenBarModule.Reset()
	end	
end)

This has a server script (for security) check the player’s head to see if they are inside the water block.
Then the server script will set an Attribute on the head to show the oxygen level
A LocalScript will check if the oxygen Attribute changes, and if it does, it will
Draw the Oxygen Bar, using the code in the OxygenBarModule.

Hope this helps in some way

1 Like

Thanks! I′ll try it tomorow… Can′t do it now.

Also a thing, how can I make the oxygen, but with oxygen upgrade?

Video of what I mean:

Next time, wait until you have all the pieces of your topic before making it.

part.Touched is a RBXScriptSignal, and therefore this loop will always run. Instead you should make a touched variable which is set to true when Touched is fired, and false with TouchEnded is fired. Or you can use part:GetTouchingParts() to determine if it’s being touched.

1 Like

Okay, I’ll try it tommorow! Thanks!

Anywas, I ran into other problem.