local Name, Collection, Tween, Info, Table = script.Name, game:GetService("CollectionService"), game:GetService("TweenService"), TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {}
local function Color(Part)
local Task, Track = nil
local function Resume()
repeat
Table.Color = BrickColor.Random().Color
Track = Tween:Create(Part, Info, Table)
Table.Color = nil
Track:Play()
task.wait(1)
until nil
end
local function Check()
if not Task and workspace:IsAncestorOf(Part) then Task = task.spawn(Resume) elseif Task then
Track:Cancel()
task.cancel(Task)
Track, Task = nil
end
end
Check() Part.AncestryChanged:Connect(Check)
end
Collection:GetInstanceAddedSignal(Name):Connect(Color)
for I, Tagged in ipairs(Collection:GetTagged(Name)) do
Color(Tagged)
end
The idea here is to cancel the operation if the part leaves workspace and resume if the part re-enters workspace to avoid burning CPU on tweening parts that are not visible. But the method I came up with is quite complex. Is there a simpler way?
Edit: I have a newer version now:
local Name, Collection, Tween, Info, Active, Tmp = script.Name, game:GetService("CollectionService"), game:GetService("TweenService"), TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {}, {}
local function Color(Part)
local Track: Tween?
local function Try()
Track[if workspace:IsAncestorOf(Part) then 'Play' else 'Pause'](Track)
end
local Signal = Part.AncestryChanged
local Connect = Signal:Connect(Try)
task.spawn(function()
repeat
Tmp.Color = BrickColor.Random().Color
Track = Tween:Create(Part, Info, Tmp)
Active[Part] = Track
Tmp.Color = nil
Track:Play()
until Track.Completed:Wait() == Enum.PlaybackState.Cancelled
Signal:Disconnect()
Active[Part] = nil
end)
Try()
end
Collection:GetInstanceRemovedSignal(Name):Connect(function(Removed)
local Track = Active[Removed]
if not Track then return end
Track:Cancel()
end)
Collection:GetInstanceAddedSignal(Name):Connect(Color)
for I, Tagged in ipairs(Collection:GetTagged(Name)) do
Color(Tagged)
end