I’ve got a functioning system that:
- Detects if you’ve touched a part to fire the client (Server script)
- OnClientEvent that clones models in ReplicatedStorage and puts it in the workspace (local script)
- CollectionService function that grabs said models in the workspace, and allows for collection (touch event referring to a part in the model)
(These models are coins, btw)
Problem is, I’m not sure how to smartly implement a debounce that generates the coins again (i.e., fire the client) only if any of the models have been collected, but not generate any coins in a spot that’s already occupied by a coin that hasn’t been collected. The models only exist in the client, so the server does not see them in the workspace. I’m trying to organize these coins by level (folders), but to keep things simple, FireClient should fire if any coins anywhere have been collected and the player touches the part again.
I’ve got a debounce for the actual touch event of the part, sort of, but nothing that really specifies to fire the client only to the above conditions.
Server Script:
local MainSpawn = game.Workspace.Lobby.LobbySpawns.LobbyCheckpoint
local Floor1TP = game.Workspace.FloorTeleports.Floor1TP
local levelStarts = {MainSpawn, Floor1TP} -- Table containing the two parts (above) that will generate the coins on touch
for _, start in pairs(levelStarts) do -- Grabs "levelStarts" and checks if either part has been touched
start.Touched:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player == nil then -- If a non-player touches these parts, do nothing
return
end
if not Touched then
Touched = true
print("client fired")
coinSpawn:FireClient(player, hit)
Touched = false
end
end)
end
Local Script:
local coinSpawn = game.ReplicatedStorage:WaitForChild("coinSpawn") -- Event that fires when the server script "CoinHandler" fires it
local CollectionService = game:GetService("CollectionService")
local Coins = CollectionService:GetTagged("Coins")
local RScoins = game.ReplicatedStorage.Coins:GetDescendants()
local Folder1 = game.Workspace.MapLevels.Level1.Coins
local coinFolders = {}
local function getCoins() -- Allows collection of coins on touch
for _, coin in pairs(Coins) do
if coin:IsA("Part") then
coin.Touched:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player == nil then
return
end
coin.Parent:Destroy() -- Removes the cloned coins from the workspace
table.remove(Coins, table.find(Coins, coin)) -- Removes destroyed coins from the collection service table
player.PlayerData.Coins.Value = player.PlayerData.Coins.Value + 1 -- Adds the coin's value to the player's coins
end)
end
end
end
function loadCoins(hit) -- Loads the coins into the game by cloning them from replicated storage
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player == nil then
return
end
for _, clonedCoins in pairs(RScoins) do -- Iterates through the coins in replicated storage
if clonedCoins:IsA("Model") then
local coinAmount = Folder1:GetChildren()
local count = #coinAmount
local clone = clonedCoins:Clone() -- Defines a cloned coin
for _, Part in pairs(clone:GetChildren()) do
if Part:IsA("Part") then
if count < 3 then return end
if count > 3 then
print("coin spawned!")
clone.Parent = Folder1 -- Parents the cloned coins into the workspace
CollectionService:AddTag(Part, "Coins")
table.insert(Coins, Part)
end
end
end
end
end
print(table.getn(Coins)) --Checks for how many coins are in the collection service table
getCoins() -- Fires the collection of coins function
end
coinSpawn.OnClientEvent:Connect(loadCoins) -- Fires "loadCoins" when the server script calls it
As the script currently stands, coins are spawned, can be collected, but can’t be re-spawned.
**EDIT: Removed a redundant variable defining the coin in the server script, as well as the additional debounce dependent on that variable.
Also tweaked the local script to include a folder count debounce I tried, but was unsuccessful.