Help with changing text from server.Touched to client through RemoteEvent

Hello there!
So I’ve been having trouble with using a RemoteEvent to change the text of a billboard GUI after a touch event has been triggered through a part. The point of the game is that you have to find gears throughout the map and put them back into the “Return Zone” and every gear you bring back it adds up one more to display on the billboard GUI.
Server script:

local Players = game:GetService("Players")

local Event = game.ReplicatedStorage.Value2Text

local Zone = script.Parent
local numValue = Zone.NumOfGears

Zone.Touched:Connect(function(plr)
	Event.OnServerEvent:Connect(function()
		local player = Players:GetPlayerFromCharacter(plr.Parent)
		if player.Backpack:FindFirstChild("Gear") then
			task.wait(0.1)
			numValue.Value = numValue.Value + 1
			player.Backpack:FindFirstChild("Gear"):Destroy()
		else
			print("No gear found")
		end
	end)
end)

Client:

local Event = game.ReplicatedStorage.Value2Text
local Zone = script.Parent.Parent
local numValue = Zone.NumOfGears
local text = script.Parent.TextLabel.Text

numValue.Changed:Connect(function(plr)
	text = (numValue.Value .. "/5")
end)

Event:FireServer()

The problem is that nothing is printing in the output
Screenshot of workspace:
Explorer
Thanks!

The main issues are that the client isn’t calling RemoteEvent:FireServer() when its Player’s character Model touches the Zone BasePart, and LocalScripts do not run in Workspace.
These are easy fixes, but your code is not structured well, so we need to fix that.


The first thing is that you’re setting up an event listener (Event.OnServerEvent) inside of another event listener (Zone.Touched), even though first one named isn’t reliant on the second one named. So, every time Zone gets touched, you’re setting up a new OnServerEvent event listener for your RemoteEvent.

This is problematic because, one, when Event.OnServerEvent fires, the code inside the connected function will run how ever many times the listener has been set up and, two, this can affect performance because of one. For example, let’s say we set up a BasePart.Touched event listener five times. When that BasePart gets touched once, the function connected to those event listeners will execute five times:

local part = workspace.Part

for _ = 1, 5 do
    part.Touched:Connect(function()
        print("The part was touched!")
    end)
end

And if you have code that increases a value inside of that function, you’d be adding extra to the value than needed.


The second thing is that you should not be relying on the client to update a value that affects the game. The server has the ability to update the value without any input from the client, and if you give the client that much responsibility, your game could be ruined by exploiters and laggy players.

I think you should just update the value when a player touches the Zone BasePart, not when a client calls Event:FireServer().


In your Script, the body of the function connected to the RemoveEvent.OnServerEvent event should be cut out and pasted into the body of the BasePart.Touched event’s connected function:

zone.Touched:Connect(function(otherPart)
    local player = Players:GetPlayerFromCharacter(otherPart)
    local gear = if player
      then player.Backpack:FindFirstChild("Gear")
      else nil

    if gear then
        gear:Destroy()
        task.wait(0.1)
        numValue.Value += 1
    end
end)

Also, if Zone gets touched multiple times at nearly the same time–a BasePart can detect all of the parts of a Player’s character touching it–and you yield before you destroy the Gear, for every body part that touches Zone under 0.1 seconds, you’d be adding to the NumberValue’s Value.


I noticed in your LocalScript that you are not setting the Text of the TextLabel. When you define a variable as an Instance’s property, you’re not storing the path to that property, you’re storing the value that’s currently being held at the time you’re defining the variable.

This means you’re not changing the property, you’re just changing the value of the variable.

Instead, just store the TextLabel and change its Text property by indexing it:

local label = -- [The TextLabel's location.]

numberValue.Changed:Connect(function(newValue)
    label.Text = newValue .. "/5"
end)

Don’t forget to put the LocalScript somewhere it can run, like StarterPlayerScripts.

1 Like

Appreciate it, was a little rusty with my remote events

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