RemoteEvents and PlayerGui

I’m trying to make it such that the weapon’s indicator in my game updates to base off what weapons in their inventory a player has whenever they spawn and therefore fire the Player.CharacterAdded event.

The template for the weapon indicator is as below:
image

The hierarchy of relevant objects is as shown:
image
image

How it works is that whenever the player respawns, a Player.CharacterAdded event within MeleeWeaponScript runs and fires the UpdateName RemoteEvent, taking several of STANDARD SWORD's details (tool references STANDARD SWORD by script.Parent) as arguments for the RemoteEvent.

player.CharacterAdded:Connect(function()
	print(player) --The reference to player has been established beforehand.
	print("Character Added " .. time())
	player:WaitForChild("PlayerGui"):WaitForChild("ScreenGui").ShakingFrame.Weapon1Frame:WaitForChild("UpdateName"):FireClient(player, tool.Name, tool.ToolTip, tool.TextureId)
	print("Fired? " .. time())
end)

Afterwards, some code within the LocalScript Weapon1Init will check for firing of the UpdateName RemoteEvent.

script.Parent.UpdateName.OnClientEvent:Connect(function(name, special, image)
	print("UPDATE NAME " .. name .. " " .. special .. " " .. time())
	script.Parent.WeaponNameText.Text = name
	script.Parent.SpecialMoveText.Text = special
	script.Parent.WeaponImage.Image = image
end)

When I go on testing, the weapon indicator seems to work as intended when I spawn for the first time (and unfortunately, only for the first time).
image

The output is as shown below (notice the time() outputs):
:green_square:squareHEADnoob
:green_square:Character Added 1.2833333993331
:green_square:Fired? 1.2833333993331
:blue_square:UPDATE NAME STANDARD SWORD [F] - LUNGE 1.3166667381302

However, if my character gets killed by any means and respawns afterwards, the weapon indicator stays as per the template (I haven’t done the proper implementation for the second weapon indicator yet):
image

The output still stays quite similar, but the OnClientEvent seems to have been called before the CharacterAdded finishes?:
:green_square:squareHEADnoob
:green_square:Character Added 292.01668190118
:green_square:Fired? 292.01668190118
:blue_square:UPDATE NAME STANDARD SWORD [F] - LUNGE 291.99584858026

From Roblox’s API on PlayerGui :
“When a player first joins a game, their PlayerGui is automatically inserted into their Player object. When the player’s Player.Character spawns for the first time all of the contents of StarterGui are automatically copied into the player’s PlayerGui. Note that if Players.CharacterAutoLoads is set to false the character will not spawn and StarterGui contents will not be copied until Player:LoadCharacter is called. If StarterGui.ResetPlayerGuiOnSpawn is set to true then every time the player’s character respawns all of the contents of that player’s PlayerGui is cleared and replaced with the contents of StarterGui.”

I’m suspecting that the entire PlayerGui gets cloned from StarterGui upon the respawning of the character. That’s why this problem happens. What would be the workaround for this then, so that the weapon indicator updates correctly every time the character spawns?

Are you sure that the problem isn’t that the server fires the remote event before the client has connected to it. For example, have you tried putting a wait in your server script just before firing the client (maybe this is the problem your describing I just wanted to clarify)?

The above obviously isn’t a good solution, but I’m just wondering if that would work.

1 Like

I’m not really sure what the best solution to this is, but maybe you could fire a remote event from the client to the server to notify the server that the client has connected to the event.

An alternative appraoch could be to disable the resetOnSpawn property on the screen gui so that the gui is not recloned to the player when they spawn.

So I did that.
MeleeWeaponScript:

player.CharacterAdded:Connect(function()
	print(player) --The reference to player has been established beforehand.
	wait() --Added.
	print("Character Added " .. time())
	player:WaitForChild("PlayerGui"):WaitForChild("ScreenGui").ShakingFrame.Weapon1Frame:WaitForChild("UpdateName"):FireClient(player, tool.Name, tool.ToolTip, tool.TextureId)
	print("Fired? " .. time())
end)

It now works as intended. Thank you. I initially put a wait() in the LocalScript as such:

script.Parent.UpdateName.OnClientEvent:Connect(function(name, special, image)
	wait()
	print("UPDATE NAME " .. name .. " " .. special .. " " .. time())
	script.Parent.WeaponNameText.Text = name
	script.Parent.SpecialMoveText.Text = special
	script.Parent.WeaponImage.Image = image
end)

But that didn’t work. I’m not too sure how I did not consider putting the wait() in the Script instead.