What the most efficient way to spin coins?

So, I want to make a local script that spins coins. I have found multiple different ways of doing this but don’t know which is the most efficient/performant. Which of the 3 following types would be the best to use?

Type 1:

 local function spinCoins()
 	for _, c in pairs(CollectionService:GetTagged(tag)) do
 		c.CFrame = c.CFrame * CFrame.Angles(0,math.rad(2),0)
 	end
 end
 
 RunService.RenderStepped:Connect(spinCoins)

Type 2: Using tweens.

Type 3: Using angular velocity.

3 Likes

once more:

if you want a voxel style animation (low fps) then def type1 ( you could make type1 slower for the less smooth )

if you want a smooth system then make a tween and make the loop infinite in the tween info (type2)

1 Like

I have tried both and they are both very smooth. With that in mind, which would be the most performant?

i think the tweening may be best, but its what ever you would like

The code you have here modifying the CFrame is fine, but you would want to move it to heartbeat instead.

To improve performance make sure you’re only moving coins that are in the players viewport and nearby. Other than that, you should be fine!

1 Like

This is the full script. Why would it be better to use Hearbeat over RenderStepped?

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local Workspace = game:GetService("Workspace")
local RunService = game:GetService("RunService")
local SoundService = game:GetService("SoundService")

local CoinEvent = ReplicatedStorage.Remotes.Coin
local Coins = Workspace:WaitForChild("Coins")
local db, db2 = false, false
local tag = "cpart"

local player = game.Players.LocalPlayer

local function onTouch(c)
	if db == false then
		db = true
		c:Destroy()
		CoinEvent:FireServer()
		SoundService.SFX.Coin:Play()
		task.wait(0.5)
		db = false
	end
end

local coins = {}

local function spinCoins()
	for _, c in pairs(CollectionService:GetTagged(tag)) do
		c.CFrame = c.CFrame * CFrame.Angles(0,math.rad(2),0)
	end
end

local function onAdded(object)
	coins[object] = object.Touched:Connect(function(p)
		if p.Parent == player.Character then
			onTouch(object)
		end
	end)
end

local function onRemoved(object)
	if coins[object] then
		coins[object]:Disconnect()
		coins[object] = nil
	end
end

CollectionService:GetInstanceAddedSignal(tag):Connect(onAdded)
CollectionService:GetInstanceRemovedSignal(tag):Connect(onRemoved)

RunService.RenderStepped:Connect(spinCoins)

for _, object in pairs(CollectionService:GetTagged(tag)) do
	onAdded(object)
end

RenderStepped runs before anything is rendered along with other things and should only be used for things like cameras, Heartbeat runs after the frame is rendered and is essentially a while task.wait() loop.

If it runs like a task.wait() loop wouldn’t tweening the object be more efficient?

No, it would mean you would be creating a tween for every coin, which is worse.