local Collection, Tween, Name, Table = game:GetService("CollectionService"), game:GetService("TweenService"), script.Name, {}
local function Color(Part)
local function Check()
while workspace:IsAncestorOf(Part) do
Table.Color = Color3.new(math.random(), math.random(), math.random())
local Tween = Tween:Create(Part, TweenInfo.new(math.random()+1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), Table)
task.defer(Tween.Play, Tween)
Tween.Completed:Wait()
end
end
Check()
Part.AncestryChanged:Connect(Check)
end
Collection:GetInstanceAddedSignal(Name):Connect(Color)
for I, Part in ipairs(Collection:GetTagged(Name)) do
Color(Part)
end
This code is designed to constantly randomize the color of certain objects via the TweenService. Any feedback?
Since you’re not running the function in a separate thread, there is a situation where the for loop is gonna pause prematurely until the part is no longer in workspace since it entered the Check while loop.
This is fine if the part starts out in workspace, but once it gets parented out of it and back the Check function will be called every single time it is reparented, so there is the possibility that the Check loop will be running multiple times for the same part, which I don’t think is behavior you desire. To fix it, maybe add some sort of flag which tells it to not start running the loop if one is already running.
task.defer running a bit later than the main thread does not change the fact that the code will wait for the tween to be completed. The yielding of the loop is necessary to make sure the colors of the part are tweened one after another, plus an infinite loop with no yielding will crash the game.
What’s your source for this? Honestly just seems like a micro-optimization to me. How slower is it actually? And would it impact the OP’s code?
A:IsAncestorOf(B) only needs to find B.Parent, and then the parent of that, etc. until either A is found or nil is found. There is no need to loop through all the descendants of the workspace.