Hi, I was wondering if anyone can help me on this.
I am trying to create a game in which there are two collectible items, one of which is a coin.
Upon touching these coins, they get added to a count and become transparent, as well as having their cantouch disabled. This is meant to be a client side script, which I have so far been able to do.
The only problem with this is that upon one player touching the coin, it becomes uncollectable for all other players, and I intend for this game to be a multiplayer game.
I have been able to set up a remote event and upon touching the coin, it fires only for the client. Supposedly this is meant to make the collection client side, but the remotefunction does not work.
I assume that this is because I have either placed the localscript in playerscripts or that the localscript does not connect to the remote event properly. This makes it so that the coin is collected more than once, which is a problem.
I haven’t really found much solutions on other pages of this site, and I don’t really know how to use remote events besides the developer page for them.
The script on the coin
local count = workspace.Coins.coincount.Value
local lplayer = game.Players.LocalPlayer
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = Instance.new("RemoteEvent")
remoteEvent.Parent = game.ReplicatedStorage
remoteEvent.Name = "coin3"
coin.Touched:Connect(function(collected)
local possiblehumanoid = collected.Parent:FindFirstChildWhichIsA("Humanoid")
if possiblehumanoid then
if possiblehumanoid.Parent == lplayer then
if script.Parent.collected.Value == false then
local player = collected.Parent
if player then
remoteEvent:FireClient(player)
end
script.Parent.collected.Value = true
end
if script.Parent.collected.Value == true then
script.Parent.CanTouch = false
end
end
end
end)
The local script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local player = Players.LocalPlayer
local redcoin1 = ReplicatedStorage:WaitForChild("coin1")
local redcoin2 = ReplicatedStorage:WaitForChild("coin2")
local redcoin3 = ReplicatedStorage:WaitForChild("coin3")
redcoin3.OnClientEvent:Connect(function(coin3get)
print("this")
workspace.Coins.coin3.Transparency = 0.5
workspace.Coins.coin3.CanTouch = false
end)
What you can do is have the coin and touched event to give the player a point on the server but once they touch the coin instead of deleting the coin have the coin add that player onto a table and anyone on that table the coin will not give a point to. Then have the coin’s sever script fire a remote event to the client to delete the coin on the client. So now you have a coin that the client sees to disappear when they touch it, but on the server it’s not actually disappearing but just disabling its effect to whoever touches it. Also you can make it check if everyone in the server has touched it already and if they have then delete it on the server just to save memory for the server.
It looks like it is working, however when I try it with more than one player, the first player is added to the table, but later players who attempt to touch the coin are not added on
local playertable = {}
local inTable = false
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = game.ReplicatedStorage.coin3
coin.Touched:Connect(function(collected)
local possiblehumanoid = collected.Parent:FindFirstChildWhichIsA("Humanoid")
local player = Players:GetPlayerFromCharacter(collected.Parent)
if possiblehumanoid then
for _,difplayer in next,playertable do
if difplayer == player then
inTable = true
if inTable then
remoteEvent:FireClient(player)
end
end
end
if not inTable then
table.insert(playertable,player)
print(player.Name .. "Intable")
end
end
end)
The reason is because you’re using inTable as a bool for the entire server. So once u set inTable to true it sets it to true for everyone. To check if someone’s in a table use
if table.find(playertable,player) then
table.insert(playertable,player)
end
Thank you, this works. I only have one issue left and it’s about how to set up a debounce.
When I touch the part, it gives about 5 coins instead of one as it takes a while for the remote event to register and the collisions to disable. I have a separate script set up for the collection system. Would I put it on that script, the script on the coin or on the local script?
Collection script:
local isTouched = false
for _,v in pairs(folder:GetChildren()) do
if v:IsA("BasePart") then
v.Touched:Connect(function(touched)
local possiblehumanoid = touched.Parent:FindFirstChildWhichIsA('Humanoid')
if possiblehumanoid then
local player = game.Players:GetPlayerFromCharacter(touched.Parent)
local leaderstats = player.leaderstats
local coinstat = leaderstats and leaderstats:FindFirstChild("coins")
if coinstat then
coinstat.Value = coinstat.Value + 1
end
coinstat.Changed:Connect(function(test)
if coinstat.Value == 8 then
if not isTouched then
local cuboidstat = leaderstats and leaderstats:FindFirstChild("Cuboids")
if cuboidstat then
print("cuboid")
cuboidstat.Value = cuboidstat.Value + 1
isTouched = true
end
end
end
end)
end
end)
end
end
Is there any way that I can edit the script so that it adds one coin to the value without adding more, like adding wait() or limiting how much a value can change in a set amount of time?
Nevermind, I just needed to add another debounce to the value change on collection