How do I make this pickup do what I wish?

Introduction

I am Ithurius, I’ve been improving, but how do I fix this script to move it over to ReplicatedStorage, then to workspace in a random location moved to, have can I add more things to make this work?


I’m trying to make it gone completely after 1 coin pickup, so that people can’t exploit 1 coin for infinite.
The issue is I have no idea how to script something even close to this.
I’ve looked upon resources and tutorials, if there was one that did this I wouldn’t post this.


The script used

This is the CollectScript which triggers a pickup:

local function onTouch(hit)
	
	-- First we check or the hit block is part of a parent (in this case the character that we need)
	if type(hit.Parent) == "userdata" then 
		
		-- Check or our parent has a valid Humanoid, if it does we either have a player or a NPC that has a Humanoid inside it
		if hit.Parent:findFirstChild("Humanoid") then 

			-- Let's see or we have a valid player..
			-- https://developer.roblox.com/en-us/api-reference/function/Players/GetPlayerFromCharacter
			local player 			=		game:GetService("Players"):GetPlayerFromCharacter(hit.Parent);
			if type(player) == "userdata" then 
				game:GetService("ReplicatedStorage").PickupEvent:FireClient(player)
			end 
		end 
	end 
end

script.Parent.Touched:Connect(onTouch)

Please help a fellow dev out and nudge me in the correct direction to make dreams possible. Thanks for reading this thread! :smiley:

1 Like

What you’ll probably want to do is add a debounce into your code (Debounce Patterns | Documentation - Roblox Creator Hub). This will allow you to make it so that your coin pickup logic only happens once, and the player is only rewarded once.

For your specific code, you would add the debounce right at the beginning of the onTouch function.

local hasBeenTouched = false

local function onTouch(hit)
	if hasBeenTouched then
        -- do nothing
    else
        -- go through the rest of your logic, and set hasBeenTouched to true at the appropriate point
        -- probably at the PickupEvent:FireClient(player) line
    end
end
2 Likes

Avoid writing empty if statements like this. You can use the negation of equality or check if a value is false over unnecessarily including a case that isn’t actually handled.

local hasBeenTouched = false

local function onTouch(hit)
    if not hasBeenTouched then
        hasBeenTouched = true
        -- Code logic
        hasBeenTouched = false
    end
end
3 Likes

If there are a lot of coins, I recommend getting tag editor. Because the editor can reduce a lot of lag. And to make it gone you use the :Destroy() command, after you fire the client

You should make a Number Value with the amount of coins and if the Value is higher then it should be you should subtract that same amount its off normal or set the value to 0 if you feel like it. This had nothing to do with scripts but its just my idea on how to easily detect anything like that.

But does this fulfill the ReplicatedStorage moved to and back to workspace? Probably not.

Thank you for your help! I will consider this in my programming days…

To randomly reposition it, you can just set the Parent of the coin to ReplicatedStorage, change the CFrame of the coin, and then reparent to the workspace.

To randomly set the position, a simple way would be to choost 3 random xyz, then multiply by a radius constant (the max distance out you want to go)

local rnd = Random.new
local radius = 15

-- In your repositioning section:
local x,y,z = rnd:NextNumber(-radius, radius), rnd:NextNumber(-radius, radius), rnd:NextNumber(-radius, radius)
coin.CFrame = CFrame.new(x,y,z)