local ServerStorage = game:GetService("ServerStorage")
local Configuration = require(ServerStorage.Configurations)
local Debounce = false
local Collect = game:GetService("ReplicatedStorage").CollectEvent
local Part = script.Parent
Part.Touched:Connect(function(hit)
local human = hit.Parent:findFirstChild("Humanoid")
if (human ~= nil) and Debounce == false then
Debounce = true
print("Touch")
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
Collect:FireServer(player,Part)
end
end)
the part the contains this local script is spawn on the client side and I dont know if thats the problem. robloxapp-20230609-1100549.wmv (1.4 MB)
It would make more sense for this to be registered on the server.
Using a remote event here means that an exploiter could repeatedly fire that event to gain a bunch of coins.
Instead, register hits on the server and use a remote event to remove the coin on the client:
local part = game.Workspace.Part
local debounce: boolean
function on_hit(other_part: Part)
if other_part.Parent:FindFirstChildOfClass("Humanoid") and not debounce then
local PLYRS: Players = game:GetService("Players")
local plyr: Player = PLYRS:GetPlayerFromCharacter(other_part.Parent)
event:FireClient(plyr, part)
end
end
part.Touched:Connect(on_hit)
… then, do something with the part on the client:
function remove_coin(part: Part)
if not part then return end
part:Destroy()
end
event.OnClientEvent:Connect(remove_coin)
Or, arguably, just handle both on the client. If the coins aren’t independent to each client, just remove them after updating a player’s coin value on the server!
I dont think he should remove the coin on the client, he should let the coin be handled on the server and also destroyed on the server, he should only use a remote event to fire to the client if he wants to add effects
Maybe instead of using a .Touched since that isnt working just have magnitudes checks on the client running in a heartbeat loop and then fire to the server that they want to collect the coin, but have the debounce for each player on the server so players cant possibly spam remotes and you can also check if the player is close to a coin aswell
You can just use one heartbeat loop for every single coin that may be in workspace, or well whereever you may store your coins
Actually, I have an idea, you can use a for loop, and a coroutine, and then wait for whatever name your part is, and what object type it is, and then do the touched event.
I might post a sample script of what i mean
Both of these codes are using server scripts:
Touch Event (SeverSided in ServerScriptService):
local ServerStorage = game:GetService("ServerStorage")
local Configuration = require(ServerStorage.Configurations)
local Debounce = false
local Collect = game:GetService("ReplicatedStorage").CollectEvent
for _, eachcoin in pairs(workspace:GetChildren()) do
if eachcoin:IsA("Part") and eachcoin.Name == 'coin' then
coroutine.resume(coroutine.create(function()
eachcoin.Touched:Connect(function(hit)
local human = hit.Parent:FindFirstChild("Humanoid")
if eachcoin ~= nil and (human ~= nil) and Debounce ~= true then
Debounce = true
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
print(player.Name)
Collect:FireServer()
Debounce = false
end
end)
end))
end
end
Is it alright if i see the other script that you have?
local Collect = game:GetService("ReplicatedStorage").CollectEvent
local part = script.Parent
function on_hit(other_part: Part)
print("Touched")
if other_part.Parent:FindFirstChildOfClass("Humanoid") then
local PLYRS: Players = game:GetService("Players")
local plyr: Player = PLYRS:GetPlayerFromCharacter(other_part.Parent)
Collect:FireClient(plyr, part)
task.wait(2)
end
end
part.Touched:Connect(on_hit)
With the Collect event, you put it in the wrong terms. At the start of the topic, in your collect script, it says FireServer(). So I think what the problem here is, instead of putting Collect.OnServerEvent:Connect(function(player, part), you put Collect.OnClientEvent:Connect(function(player, part). It is a difference from the Server and the Client, since you are using a ServerScript, you would put Collect.OnServerEvent:Connect(function(player, part), not Collect.OnClientEvent:Connect(function(player, part).
nvm
The code below would be in a ServerScript:
local ServerStorage = game:GetService("ServerStorage")
local Debounce = false
local Collect = game:GetService("ReplicatedStorage").Collect
for _, eachcoin in pairs(workspace:GetChildren()) do
if eachcoin:IsA("Part") and eachcoin.Name == 'coin' then
coroutine.resume(coroutine.create(function()
eachcoin.Touched:Connect(function(hit)
local human = hit.Parent:FindFirstChild("Humanoid")
if eachcoin ~= nil and (human ~= nil) and Debounce ~= true then
Debounce = true
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
print(player.Name)
eachcoin:Destroy()
Collect:FireClient(player,eachcoin)
Debounce = false
end
end)
end))
end
end
The code below is in a LocalScript:
local Collect = game:GetService("ReplicatedStorage").Collect
local Configuration = {
GEM_COLLECT = 1 * 2
}
local value = 0
Collect.OnClientEvent:Connect(function(player, part)
value = value + Configuration.GEM_COLLECT
print(value)
end)