GUI does not show up after player resets

Ok, I have a really strange problem here. I have a GUI for players that shows level, scores, timer, etc… However, when the player resets, parts of the GUI no longer show up. See below:

Before Reset

After Reset

Now I have done a little bit of research and found that in the ScreenGui one should set the ResetOnSpawn to false. In my configuration, it is set to true. What’s strange is that level bar comes back and it’s under the same ScreenGui instance that the rest of the UI is. Also, I added some print statements to the code and things are printing out as they are supposed to, so the server is sending the command to display it. I even placed a print statement right where it sets Visible to true, but the Visible flag just isn’t getting checked when it’s commanded to.

Here’s some of the relevant code.

-- Shows the scores for four team play.
local function showTeam4Score()
	local playerGui = localPlayer:WaitForChild("PlayerGui", childWaitTime)
	if playerGui ~= nil then
		local gameGui = playerGui:WaitForChild("GameGUI", childWaitTime)
		if gameGui ~= nil then
			local status = gameGui:WaitForChild("Status", childWaitTime)
			print("status", status)
			if status ~= nil then
				local scoreTeamRed = status:WaitForChild("ScoreRed", childWaitTime)
				print("scoreTeamRed", scoreTeamRed)
				if scoreTeamRed ~= nil then
					print("scoreTeamRed", "Visible")
					scoreTeamRed.Visible = true
				end
				local scoreTeamBlue = status:WaitForChild("ScoreBlue", childWaitTime)
				if scoreTeamBlue ~= nil then
					scoreTeamBlue.Visible = true
				end
				local scoreTeamGreen = status:WaitForChild("ScoreGreen", childWaitTime)
				if scoreTeamGreen ~= nil then
					scoreTeamGreen.Visible = true
				end
				local scoreTeamYellow = status:WaitForChild("ScoreYellow", childWaitTime)
				if scoreTeamYellow ~= nil then
					scoreTeamYellow.Visible = true
				end
				status.Visible = true
				gameGui.Enabled = true
			end
		end
	end
end

I also double checked what was coming from the server. The correct commands are being sent. On a hunch, I restarted Studio and it’s still doing it. It’s also doing it in the live server too. So I have no idea what’s going on.

Any ideas or suggestions are welcome.

Not sure if this will work but select the ScreenGui objects that are experiencing the issues in StarterGui and turn off ResetOnSpawn

I did that and everything really got messed up. The problem is everything is under GameGui and some items under that have the issue and some don’t. It’s strange. As I said, the server is sending the correct commands to the client to display stuff. So I’m not sure if it’s some kind of bug or what’s going on.

Why don’t you just enable the visible without needing the if nil statemnts.

It’s part of the robust coding principle, also known as defensive coding. Since I have no control over whether WaitForChild returns nil or not, I have to check for it. Since the code is part of a module, if it errors out, the client will break. I code like that to prevent those errors from breaking the client.

Yeah, I don’t know anything else as I haven’t seen the error code line.

Is the GUI enabled false? or visible on all images or frame false?

@AviaNexo
There are no errors. The code executes properly, both times. The frame just will not display and Visible is still false, even after setting it to true.

@X0BaconHairDude0X
GUI enabled defaults to false and visibility on all frames default to false as well. As you can see in the code, I am explicitly setting those to true. It’s just that the true doesn’t want to take for some reason.

As per the screenshots, this does work when the player first loads in, but does not work when they reset. The same code gets executed both times. Furthermore, the level indicator which is on the same screen GUI as the status (timer and scores) does display, so it’s not a GUI problem.

What am I missing?

Do these in every making frame visible if statements
print("visible")

Did that. Also not posted in the original code, I also did print("scoreTeamRed Visible:", scoreTeamRed.Visible) right after it set to true and it prints true. When I go check it in the client in Studio, it’s false. The hide functions are not being called either. It does not make sense.

My guess is that this script only gets executed like once, then it won’t comeback after death? Where is the script you supplied?

The script is actually a module script that is located under it’s loader LocalHandler which is under StarterPlayerScripts. The script does run when the character respawns. The printouts actually show that, and it’s in the screen shot. The server commands when the character respawns is the same as the commands when the character initials loads in the game.

From what I see is that the guis exist but their visible property is set to false, so somewhere in your script they are being put so they aren’t true. Could you think of a place where the script set it to false?

I did think about that. The only place that happens is in the hide functions, and the hide all GUI elements function, but those are not running.

So after fighting this for awhile, I figured it out. For whatever reason, when the character initially loads, the level bar is commanded to display first, then the whole status frame afterwards. When the character resets, the server commands the status frame to show first and then the level bar. I placed a 1 second delay in the code on the server where the display status is triggered from, and now it works. I’m not sure why the order matters since it shouldn’t. Both the level indicator and the status bar operate independently of each other and both enable the screen GUI and their respective frames. I don’t think it’s a loading issue since the WaitForChild calls ensure that all the elements are loaded and present before they are being used.

Here’s my code that displays the level indicator:

-- Shows the game level indicator GUI.
local function showLevelIndicator()
	local playerGui = localPlayer:WaitForChild("PlayerGui", childWaitTime)
	if playerGui ~= nil then
		local gameGui = playerGui:WaitForChild("GameGUI", childWaitTime)
		if gameGui ~= nil then
			local level = gameGui:WaitForChild("Level", childWaitTime)
			if level ~= nil then
				local levelBar = level:WaitForChild("LevelBar", childWaitTime)
				if levelBar ~= nil then
					levelBar.Visible = true
				end
				local levelText = level:WaitForChild("LevelText", childWaitTime)
				if levelText ~= nil then
					levelText.Visible = true
				end
				local levelNumber = level:WaitForChild("LevelNumber", childWaitTime)
				if levelNumber ~= nil then
					levelNumber.Visible = true
				end
				local currXP = level:WaitForChild("CurrentXP", childWaitTime)
				if currXP ~= nil then
					currXP.Visible = true
				end
				local nextXP = level:WaitForChild("NextLevelXP", childWaitTime)
				if nextXP ~= nil then
					nextXP.Visible = true
				end
				local slash = level:WaitForChild("Slash", childWaitTime)
				if slash ~= nil then
					slash.Visible = true
				end
				level.Visible = true
				gameGui.Enabled = true
			end
		end
	end
end

It’s in the same module and enables the same screen GUI.

What I may do is separate the timer from the score board and overlay the timer frame on the score board. The issue why I can’t have it enabled at all times is because different game modes have different scoring requirements. There’s highest score for a free for all game, then team games have their own scoring based on two teams or four teams. The timer may or may not be used depending on the configuration of the game mode.

Glad you fixed it, for me it never has happened before.

You know, this is the second time that I ran into this. The first time was with the level indicator. I looked at that code, and I have a task.wait(0) before it sends the commands to the client. I think part of the problem is that the thread executes with no break but one is needed. So the task.wait(0) is basically being used like a pthread.yield().