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.
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
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
Only detect area just by touching, not render distance or loop to check.
There no physic use it’s totally use Tween
I write these script totally avoid from any memory leak
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)