Coin drop system

I have been wondering for a while how I would go about making a system that shoots out coins and drops from a model which then fall to the ground to be collected by the player. Kinda like Pet Simulator does it. I would expect it to be done by applying some kind of velocity. But I don’t really know about the steps after it.

I know I could use lerps to imitate a parabolic motion but I don’t think this is the most optimised option. So if anyone knows how I could achieve this, feel free to help me out.

2 Likes

clone model → set position → play animation → detect if the player collided or interacted with model → apply values on server

I didn’t bother typing any code out but gave you the general gist of how they work

1 Like

Yea but how do you animate it through code, that’s the part i don’t know how to do.

1 Like

you could use AlignPosition and set the position property to the player position in a renderstepped loop, or make it follow a bezier curve if you want parabolic motion

1 Like

either make an animation or just tween the position + let gravity to the work

1 Like

Coin drop example + tween.rbxl (66.5 KB)
You can try it if want. i also showcase how is it work. well try take look memory doesn’t went up too much

Script

local plrs=game:GetService'Players'
local CS=game:GetService'CollectionService'
local TS=game:GetService'TweenService'
local COIN_AREA=workspace.Coin_area
local COINOBJECT=game.ServerStorage.Coin

-- Configure
local MaxCoin=100
local COINDROP_PERSEC=.1
local DELAYBEFORECOINDELETE=10
-- Value better don't mess up
local COINAREAGOING,ISLOOP,calculate,Coin_inthere=false,false,0,0
local coin=nil -- example prevent make another local
local COINOBJ={}
local COINTAG='COIN'

-- example i took for collectionservice used instance coin spawn for prevent memory leak ( not always 100% work )
-- https://devforum.roblox.com/t/i-would-like-to-see-examples-of-collection-service-in-use/176616/8
-- it relies less on language features new developers might not be familiar with such as metatables. It also has more detailed comments.

-- If we remove the coin tag from an instance, or the instance is removed from the world, this will be called

local function NEWCOIN(instance)
local COINV={instance=instance,run=true,}

function COINV:destroy()
-- Stop the sequence if it's not too late
self.running=false
end
function COINV:runSequence()
self.instance.Touched:Connect(function(p)
if plrs:FindFirstChild(p.Parent.Name)and self.instance.CanTouch then
self.instance.CanTouch=false -- I just avoid being multiple trigger
plrs[p.Parent.Name].leaderstats.Coin.Value+=1
CS:RemoveTag(self.instance,'COIN')
-- Clean up the leftover coin
self.instance:Destroy()
end
end)
end
-- Kick off the coin sequence as soon as the coin is created
spawn(function()COINV:runSequence()end)return COINV end

local function COIN_DELETED(instance)
Coin_inthere-=1
for i=1,#COINOBJ do
if COINOBJ[i] then
table.remove(COINOBJ,i)
end end end

local function COIN_ADDED(instance)
Coin_inthere+=1
COINOBJ[#COINOBJ+1]=NEWCOIN(instance)
end

CS:GetInstanceRemovedSignal(COINTAG):Connect(COIN_DELETED)
CS:GetInstanceAddedSignal(COINTAG):Connect(COIN_ADDED)

COIN_AREA.Touched:Connect(function(p)
if p.Parent and plrs:FindFirstChild(p.Parent.Name)then -- Verify if it's a Player
if plrs[p.Parent.Name]:HasTag'COINAREA_1'then -- Check is player already in?
else
CS:AddTag(plrs[p.Parent.Name],'COINAREA_1')
end
if not ISLOOP then -- Check if loop already run or no?
ISLOOP=true COINAREAGOING=true
while task.wait(COINDROP_PERSEC)do -- Loop starting once player is avaible
if COINAREAGOING then -- Check is it going run else if false going break
coin=COINOBJECT:Clone()
coin.Position=Vector3.new(
 COIN_AREA.Position.X+math.random(-COIN_AREA.Size.X/2,COIN_AREA.Size.X/2),
 COIN_AREA.Position.Y+20,
 COIN_AREA.Position.Z+math.random(-COIN_AREA.Size.Z/2,COIN_AREA.Size.Z/2)
)
coin.Parent=workspace.Coins
task.delay(0,function()
local tween=TS:Create(coin,
 TweenInfo.new(2,
 Enum.EasingStyle.Bounce,
 Enum.EasingDirection.Out),
 {Position=Vector3.new(coin.Position.X,(-coin.Size.Y/2)+.5,coin.Position.Z)})
tween:Play()
tween.Completed:Once(function() -- Function will remove once done
tween:Destroy() -- clean up tween
end)
end)
game.Debris:AddItem(coin,DELAYBEFORECOINDELETE)
coin:AddTag('COIN')
else ISLOOP=false
break -- Loop going stop				
end
end
end
end
end)

workspace.coin_area_left.Touched:Connect(function(p) -- I don't think soo TouchEnded still worst way
if p.Parent and plrs:FindFirstChild(p.Parent.Name)then
CS:RemoveTag(plrs[p.Parent.Name],'COINAREA_1')
for i,v in pairs(CS:GetTagged'COINAREA_1')do-- Check if there any player left
calculate+=1
end
if calculate==0 then -- This is actually when no one there
COINAREAGOING=false
end
calculate=0 -- Make sure to clear at 0
end
end)

plrs.PlayerRemoving:Connect(function(p) -- You might need this to detect if player it's leave ( Do you think need???)
if CS:HasTag(p,'COINAREA_1')then
CS:RemoveTag(p,'COINAREA_1')
end end)

local val,vcoin -- try as possible to not add local inside function
plrs.PlayerAdded:Connect(function(p)
val=Instance.new('Folder',p)
val.Name='leaderstats'
vcoin=Instance.new('IntValue',val)
vcoin.Name='Coin'
vcoin=nil
val=nil
end)

If something wanna added i will try!

1 Like
script.Parent.Activated:Connect(function()
	local part = Instance.new("Part")
	part.Position = script.Parent.Part.Position
	part.Parent = workspace
end)

Some sample code but I think you get the idea.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.