How to make ClickDetector change a GUI for everyone?

Sup, I want to make a Battery pick-up system for me and my friend’s horror game. The system is already in working order except for one thing.

There are 6 imageLabels on the players screen showing how many batteries are left to collect. One of the imageLabels turn white when a battery is picked up.

The problem is with the color switching, the colors change, but only for the person who picked the battery up. The sound for the battery pick up plays, the battery gets sent to ServerStorage when clicked but it doesn’t change the ImageLabel Color.

I couldn’t upload any videos showing this but you probably get the idea

I tried to make it work using Remote Events and making the ClickDetector fire the Remote Event when clicked and it should change the Color of the Image.
It still played the sound and moved the Battery to ServerStorage, but didn’t change the Color at all (Not even for the player who picked it up)

This is the script using the Remote Event:

local Battery = script.Parent
local PickedUp = game.ReplicatedStorage.PickedUp

local ClickDetector = Battery.ClickDetector
local Sound = script.Parent.Pickup

ClickDetector.MouseClick:Connect(function(Player)
	PickedUp:FireAllClients()
	Battery.Parent = game.ServerStorage
	PickedUp.OnServerEvent:Connect(function()
		Player.PlayerGui:FindFirstChild("BatteryHUD").Frame.B1.ImageColor3 = Color3.fromRGB(255, 255, 255)
		Sound:Play()
		Battery.Parent = game.ServerStorage
	end)
end)

This is the script that doesn’t use the remote event (Only changes color for the player who picked it up):

local Battery = script.Parent
local Players = game:GetService("Players")

local Player = game.Players.LocalPlayer

local ClickDetector = Battery.ClickDetector
local Sound = script.Parent.Pickup

ClickDetector.MouseClick:Connect(function(Player)
	Player.PlayerGui:FindFirstChild("BatteryHUD").Frame.B1.ImageColor3 = Color3.fromRGB(255, 255, 255)
	Sound:Play()
	Battery.Parent = game.ServerStorage
end)

It would help a lot if someone explained what I did wrong at the RemoteEvent script cuz I just started learning about them. I don’t need anyone to rewrite scripts. I just need someone to explain the problem in simple terms.

correct me if I’m wrong but why are you trying to fire the remote to all clients?

PickedUp:FireAllClients()

also this line:

PickedUp.OnServerEvent:Connect(function()

will only listen to the client’s side. it won’t listen to PickedUp:FireAllClients()
if so you should make the necessary changes locally.

ClickDetector.MouseClick:Connect(function(Player)
	PickedUp:FireAllClients()
	
	Battery.Parent = game.ServerStorage -- these 2 will trigger for everyone cuz it's server sided
	Sound:Play()
end)

local script:

PickedUp.OnClientEvent:Connect(function()
	-- do the local changes here
end)

OR alternatively without remote events (changes from server):

ClickDetector.MouseClick:Connect(function(playerWhoClicked)
	for _, player in pairs(game.Players:GetChildren()) do -- it'll loop for all players in that server
		player.PlayerGui:FindFirstChild("BatteryHUD").Frame.B1.ImageColor3 = Color3.fromRGB(255, 255, 255)
	end
	
	Battery.Parent = game.ServerStorage -- you only these 2 to trigger once cuz it's server sided
	Sound:Play()
end)

i may have gotten the wrong idea from ur script tho, so correct if i’m wrong

It still didn’t work none of them changed the ImageColor nor locally nor server sided.
These are the updated scripts since I could’ve maybe updated them wrong:

Remote Event version:

Server Sided:

local Battery = script.Parent
local PickedUp = game.ReplicatedStorage.PickedUp

local ClickDetector = Battery.ClickDetector
local Sound = script.Parent.Pickup

ClickDetector.MouseClick:Connect(function(Player)
	PickedUp:FireAllClients()
	Battery.Parent = game.ServerStorage
	Sound:Play()
end)

Local script:

local PickedUp = game.ReplicatedStorage.PickedUp


PickedUp.OnClientEvent:Connect(function(Player)
	Player.PlayerGui:FindFirstChild("BatteryHUD").Frame.B1.ImageColor3 = Color3.fromRGB(255, 255, 255)

end)

The version without the remote event:

local Battery = script.Parent
local Players = game:GetService("Players")


local Player = game.Players.LocalPlayer

local ClickDetector = Battery.ClickDetector
local Sound = script.Parent.Pickup

ClickDetector.MouseClick:Connect(function(playerWhoClicked)
	for _, player in pairs(game.Players:GetChildren()) do -- it'll loop for all players in that server
		player.PlayerGui:FindFirstChild("BatteryHUD").Frame.B1.ImageColor3 = Color3.fromRGB(255, 255, 255)
	end

	Battery.Parent = game.ServerStorage -- you only these 2 to trigger once cuz it's server sided
	Sound:Play()
end)

weird… the version without remote event should’ve worked.

your local script is not quite right
.OnClientEvent won’t pass any argument by default, so the argument ‘Player’ there is nil.

try changing your local script to:

local PickedUp = game.ReplicatedStorage.PickedUp
local Player = game.Players.LocalPlayer -- you need to define the player locally

PickedUp.OnClientEvent:Connect(function()
	Player.PlayerGui:FindFirstChild("BatteryHUD").Frame.B1.ImageColor3 = Color3.fromRGB(255, 255, 255)
end)

It still didn’t work, I honestly can’t quite think of a reason behind it. There were no errors in the output. Could it perhaps be the local script’s location?

Can you record a quick video if possible? it’ll help to understand what’s going wrong

robloxapp-20230425-1924591.wmv (2.3 MB)

The red battery HUD is meant to turn one of the batteries white when a battery is picked up.

local Battery = script.Parent
local Players = game:GetService("Players")


local Player = game.Players.LocalPlayer

local ClickDetector = Battery.ClickDetector
local Sound = script.Parent.Pickup

ClickDetector.MouseClick:Connect(function(playerWhoClicked)
	for _, player in pairs(game.Players:GetChildren()) do -- it'll loop for all players in that server
		player.PlayerGui:FindFirstChild("BatteryHUD").Frame.B1.ImageColor3 = Color3.fromRGB(255, 255, 255)
	end

	Battery.Parent = game.ServerStorage -- you only these 2 to trigger once cuz it's server sided
	Sound:Play()
end)

hold on, is this script a LocalScript by any chance? just noticed this as you used game.Players.LocalPlayer there.

you should change it to Script.

That is a server sided script.

can you screenshot your game’s workspace? can’t conclude anything from the video (yes it just doesn’t change the battery ui to white)

I disable and enable the scripts when switching between the remote event version and the other one.

Okay yeah, I don’t think there is anything wrong with your workspace.

How about your StarterGui?
Everything worked except for your UI changes, so it seems like something is wrong there.

Ekrānuzņēmums 2023-04-25 194106

Ah, took me a while to realize.
You put your LocalScript(s) directly under the battery in Workspace. Remember that LocalScripts don’t run under Workspace.

Put it under BatteryHUD ScreenGui. (ONLY NEED ONE, SEE BELOW TO MAKE THINGS SIMPLER)

So it should be like this:
Server-sided script: (need one under each battery)

local Battery = script.Parent
local PickedUp = game.ReplicatedStorage.PickedUp

local ClickDetector = Battery.ClickDetector
local Sound = script.Parent.Pickup

ClickDetector.MouseClick:Connect(function(Player)
	PickedUp:FireAllClients()
	Sound:Play()
	Battery.Parent = game.ServerStorage
end)

Client-sided LocalScript:

local PickedUp = game.ReplicatedStorage.PickedUp
local Player = game.Players.LocalPlayer -- you need to define the player locally
local BatteryHUD = script.Parent -- define it here 

PickedUp.OnClientEvent:Connect(function()
	for _, batteryUI in pairs(BatteryHUD.Frame:GetChildren()) do
		if batteryUI.ImageColor3 ~= Color3.fromRGB(255, 255, 255) then -- checks if it has been changed to white before
			batteryUI.ImageColor3 = Color3.fromRGB(255, 255, 255)
			break -- break the loop so that it only changes one battery ui color
		end
	end
end)
1 Like

Holy crap dude it works.

You seriously fixed a long lasting bug for the game, I will put you in the credits section on the main menu. You helped the game a lot.
Thank you.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.