Problems with Changing the Size of a Progress Bar

Howdy, I’m working on a progress bar relating to the time a terminal is being captured. For some odd reason, nothing changes at all? Guis have never been my strong suit.

A red colored bar is meant to slowly form across.
image

game.ReplicatedStorage.TerminalValues.RaidStarted.Event:Connect(function()
	local ammount = 438/game.ReplicatedStorage.TerminalValues.SetupValues.SetMax.Value
	
	while wait()do
		local capped = game.ReplicatedStorage.TerminalValues.TermCap.Value
		script.Parent.Size = UDim2.new(capped/ammount,0,0.618,0)
	end
	
	
end)

image


(And yes, the TermCap value does update over time, everything else works.)

If somebody can help, I’d greatly appreciate it.

Not really sure but was there any errors?

Try using a LocalScript instead of a regular script. Also, this part right here:

game.ReplicatedStorage

Try using game:GetService("ReplicatedStorage") like this:

local repl = game:GetService("ReplicatedStorage")
local terminal = repl:WaitForChild("TerminalValues")

then use the rest of the script, replacing all game.ReplicatedStorage.TerminalValues with just terminal.

None, otherwise I’d include that. I believe it has something to do with not tweening? I don’t work with Guis and am currently trying to find a fix.

Good idea, I’ll try that. Perhaps that might be the issue.

We generally use a local script instead of a regular script for a GUI. If you want to make it for the full server try using RemoteEvents

Unfortunately, this didn’t change much.

game.ReplicatedStorage.TerminalValues.RaidClient.OnClientEvent:Connect(function()
	local ammount = 438/game.ReplicatedStorage.TerminalValues.SetupValues.SetMax.Value

	while wait()do
		local capped = game.ReplicatedStorage.TerminalValues.TermCap.Value
		script.Parent.Size = UDim2.new(capped/ammount,0,0.618,0)
	end


end)

Nothing happened. (RemoteEvent was fired.)

You shouldn’t be modifying GUI in server scripts. Servers don’t need a GUI, clients do. What you should do instead is the following:

  1. I highly suggest moving your server scripts to ServerScriptService. The server script should not need access to GUI elements.
  2. In your server script, you should only handle data (such as changing InstanceValues, like a NumberValue for a timer).
  3. In a LocalScript (which you can place where your server scripts currently are), you listen to the Changed event of InstanceValues and, whenever the event is received, process whatever the new value of the InstanceValue is. In the case of your GUI bar, you would listen to the Changed event of a timer and update the size of your progress bar accordingly

These steps properly split your code between the server and client. The server processes data, and the client responds to the data through changes in GUI. The server does not need access to the GUI because it doesn’t have an interface to begin with.

1 Like

I’ve changed a few things around, yet nothing works.

local Player = game.Players.LocalPlayer
local Bar = script.Parent.Bar

game.ReplicatedStorage.TerminalValues.RaidClient.OnClientEvent:Connect(function()
	
	local Max = game.ReplicatedStorage.TerminalValues.SetupValues.SetMax
	local Cap = game.ReplicatedStorage.TerminalValues.TermCap
	
	while wait()do
		Bar.Size = UDim2.new(1/Cap.Value,0,1,0)
	end
	
end)

image
(Crossed out script is irrelevant.)

And yes, this IS in a LocalScript. RaidClient is also fired.

So, I just found a similar post like this. You should check it out;
Here

I assume that your TermCap value is what the size of the progress bar should be. In this case, I’d recommend changing your local script’s code such that rather than changing the size of the bar in that while wait() loop (which seems to be an infinite loop, by the way) you change the size by listening to the Changed event of TermCap. Here’s what the code could look like:

local Player = ...
local Bar = ...
local TerminalValues = game:GetService("ReplicatedStorage").TerminalValues
local TermCap = TerminalValues.TermCap

-- Setup a connection to the Changed event of TermCap
TermCap.Changed:Connect(function(value)
    -- This print statement is optional. Include it to make sure this code both works and works *as expected* (no bugs)
    print("Value of TermCap changed! Value currently: " .. value)
    
    -- Set size of bar according to the new value of TermCap
    Bar.Size = UDim2.new(1 / Cap.Value, 0, 1, 0)
end)

In case you are wondering, the Changed event is an event that is fired by all instances any time the value of one of their properties is changed. For example, if a Humanoid’s Health was changed, the Humanoid’s Changed event would fire. However, there is a slight difference between the Changed event of InstanceValues versus the Changed event of other Instances. For InstanceValues (NumberValues, CFrameValues, etc), the argument provided through the Changed event is the value of the InstanceValue’s Value (i.e. a NumberValue’s value changes to “3”, so Changed is fired with the number 3 as an argument) as opposed to the name of the property that was changed (if a Humanoid’s Health changed, the argument passed is the string “Health” rather than what the actual health is).

I suggest you do your connection in the way I proposed because every time the value of TermCap is changed, your clients will receive the Changed event immediately. This also means that whenever the value of TermCap is not changed, the client will not need to do anything. Contrast this to a constantly running while wait() (or while true do wait()) loop. When TermCap isn’t changing, your while loop would still be running, which takes up unnecessary resources.

Whenever you think you need some kind of constantly running while wait() loop, try to think if there is some kind of event you can connect (or create and then connect) to. This will free up resources for your computer (although for any events you do connect to, remember to consider disconnecting them as well if possible. I read from some post on Lua Learning that leaving your connections connected is a super easy way to take up memory and lag your game).

The code I presented does not regard times in which you do not need to deal with the progress bar (i.e. showing the raid progress is not necessary). If this is true in a way such that the progress bar only needs to be dealt with whenever the RaidClient event is received, then you can consider doing one of the following:

  1. Make a boolean variable that dictates when it is necessary to change the size of the bar. Wrap the Bar.Size = ... part of the code in an if statement that only lets that line of code run when the boolean variable allows it to. When the RaidClient event is received, set the variable accordingly.
  2. Save memory by disconnecting the Changed event connection. Change it so that whenever RaidClient is received, the connection is created in there. Store the connection in a variable. Whenever a different event is fired that informs the user that the raid has ended, disconnect the connection.

Hopefully I understood your question and situation correctly such that this post helps.

1 Like