The best way I can think of to accomplish this is to store the total speed boost each player should have in a table, and then apply it to the character each timed they spawn.
Overview
First we need to start off by adding every player who joins to an array. In this array, we'll set the key to the player's name and the value to the amount of speed the player should be boosted. We'll also set it up so that every time a character is respawned, the player will be given the speed boost value associated to their name.
local speedBoost = {}
game.Players.PlayerAdded:connect(function(player)
speedBoost[player] = 0
player.CharacterAdded:connect(function(character)
character.Humanoid.WalkSpeed = character.Humanoid.WalkSpeed + speedBoost[player]
end)
end)
Now we have to set up some kind of communication between this script, and the touched script of all the speed boost blocks in your game. To do this I will use a BindableEvent which allows for communication between two scripts (Can not communicate cross scope, local to server and vice versa. Use a RemoteEvent for this functionality). We'll put this object in the replicated storage so it is easily accessible.
local AddToSpeedBoost = Instance.new("BindableEvent")
AddToSpeedBoost.Name = "AddToSpeedBoost"
AddToSpeedBoost.Parent = game.ReplicatedStorage
AddToSpeedBoost.Event:connect(function(player, boost)
speedBoost[player] = speedBoost[player] + boost
end
In order to make it so you can only activate it once however, I will use a table that has each player who has touched the brick inserted into it and use a function to search whether or not the player who touched the brick is in the table
local touched = {}
local function PreviouslyTouched(player)
for _, value in ipairs (touched) do
if value == player then
return true
end
end
return false
end
All we have left to do now is write the touched script. I used a very similar one to yours, just modified the placement of the connection line. When you do the check if the player has touched it or not, you can then fire the BindableEvent and it will add to the player's total speed boost.
script.Parent.Touched:connect(function(part)
local player = game.Players:GetPlayerFromCharacter(part.Parent)
if player and not PreviouslyTouched(player) then
game.ReplicatedStorage.AddToSpeedBoost:Fire(player, 5)
table.insert(touched, player)
end
end)
You can have as many speed boosts as you want in your game, and it will just add to the total.
Full Scripts
Server Script In Workspace:
local speedBoost = {}
local AddToSpeedBoost = Instance.new("BindableEvent")
AddToSpeedBoost.Name = "AddToSpeedBoost"
AddToSpeedBoost.Parent = game.ReplicatedStorage
game.Players.PlayerAdded:connect(function(player)
speedBoost[player] = 0
player.CharacterAdded:connect(function(character)
character.Humanoid.WalkSpeed = character.Humanoid.WalkSpeed + speedBoost[player]
end)
end)
AddToSpeedBoost.Event:connect(function(player, boost)
speedBoost[player] = speedBoost[player] + boost
end
Server Script In Speed Boost Block:
local touched = {}
local function PreviouslyTouched(player)
for _, value in ipairs (touched) do
if value == player then
return true
end
end
return false
end
script.Parent.Touched:connect(function(part)
local player = game.Players:GetPlayerFromCharacter(part.Parent)
if player and not PreviouslyTouched(player) then
game.ReplicatedStorage.AddToSpeedBoost:Fire(player, 5)
table.insert(touched, player)
end
end)