Color Tweening not working

I have this code that is meant to rotate a part and eventually switch the rotation, which works. However, the part where it should change the color and light emission of all particles and beams within the part’s attachments does not seem to work, as it instead makes the particles disappear momentarily, change the color, and the spinning ends up breaking. (Albeit it’s a script partially made by ChatGPT)

Here’s the video:

If anyone can fix this issue, or even fix the script in a way you see fit, I would appreciate it a lot.

Here is the code:

local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")

local part = script.Parent

-- Spin settings
local spinSpeed = 1
local spinDirection = 1
local spinValue = Instance.new("NumberValue")
spinValue.Value = spinSpeed * spinDirection

-- Timing
local tweenTime = 2
local waitBeforeReverse = 3
local tweenInfo = TweenInfo.new(tweenTime, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)

-- Collect particle and beam elements only once
local function getVisualElements(parent)
	local elements = {}
	for _, descendant in ipairs(parent:GetDescendants()) do
		if descendant:IsA("ParticleEmitter") or descendant:IsA("Beam") then
			table.insert(elements, descendant)
		end
	end
	return elements
end

local visuals = getVisualElements(part)

-- Color tween using TweenService on helper proxy (avoid runtime reset!)
local function tweenColor(elements, fromColor, toColor, duration)
	local proxy = Instance.new("Color3Value")
	proxy.Value = fromColor
	local tween = TweenService:Create(proxy, TweenInfo.new(duration, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut), {Value = toColor})
	tween:Play()

	local conn = RunService.Heartbeat:Connect(function()
		for _, e in ipairs(elements) do
			pcall(function()
				e.Color = ColorSequence.new(proxy.Value)
			end)
		end
	end)

	tween.Completed:Wait()
	conn:Disconnect()
	proxy:Destroy()

	-- Final snap
	for _, e in ipairs(elements) do
		pcall(function()
			e.Color = ColorSequence.new(toColor)
		end)
	end
end

-- Tween LightEmission smoothly
local function tweenLightEmission(elements, fromValue, toValue, duration)
	local tweens = {}

	for _, e in ipairs(elements) do
		if e:IsA("ParticleEmitter") or e:IsA("Beam") then
			pcall(function()
				e.LightEmission = fromValue
				local tween = TweenService:Create(e, tweenInfo, {LightEmission = toValue})
				tween:Play()
				table.insert(tweens, tween)
			end)
		end
	end

	for _, tween in ipairs(tweens) do
		tween.Completed:Wait()
	end
end

-- Tween the spinValue
local function tweenSpin(toValue)
	local tween = TweenService:Create(spinValue, tweenInfo, {Value = toValue})
	tween:Play()
	tween.Completed:Wait()
end

-- Spin logic
RunService.Heartbeat:Connect(function()
	part.Orientation += Vector3.new(0, spinValue.Value, 0)
end)

-- Main loop
while true do
	wait(waitBeforeReverse)

	-- Step 1: Slow down, fade to black, dim light
	tweenSpin(0)
	tweenColor(visuals, Color3.new(1, 1, 1), Color3.new(0, 0, 0), tweenTime)
	tweenLightEmission(visuals, 1, 0, tweenTime)

	-- Reverse spin direction
	spinDirection *= -1

	-- Step 2: Resume spin in opposite direction, fade to white, brighten
	tweenSpin(spinSpeed * spinDirection)
	tweenColor(visuals, Color3.new(0, 0, 0), Color3.new(1, 1, 1), tweenTime)
	tweenLightEmission(visuals, 0, 1, tweenTime)
end

In other words, your tweenColor function has a pcall, which will prevent errors from being displayed in your output window. Start by removing it and seeing if any errors are being thrown. And do try to actually correct it yourself instead of plugging the error into an LLM; I’ve found that LLMs are as bad at correcting their own code as they are at trying to generate something readable.

As for my own suggestion, I always start with adding logpoints to the problem to figure out the values, and then trace where the values are coming from. In your case, it might look like tracking down all the variables being passed to the functions. From there, you could try to fix it yourself or ask a better informed question.

2 Likes

That called “ignorance” btw.
Not only is the thing he doing are insane optimization wise but he is fully aware that “code sucks” and keeps this “coping method” and then wonders why does nothing work right.

He has to remove such unneeded awful to see things and then maybe error code will tell the true cause of an issue.

What is the intended sequence, exactly? Currently, everything runs on the same thread, and each function waits until its tween(s) is/are complete before moving on, so each step blocks the next step from running rather than them being performed together. That seems like it might be intentional with the spinning blocking the Color/LightEmission changes, but this sequence separation causes the effects to briefly have their Color set to (0, 0, 0) while their LightEmission is 1, resulting in them being invisible.

For tweenSpin and tweenColor, the only consequence of their blocking behavior, is, well, that they block execution of the following code; however, tweenLightEmission’s implementation causes the script to yield indefinitely if it acts upon more than one ParticleEmitter. This is because the while the first tween.Completed:Wait() behaves as expected, the next tween in the array has already finished by the time the method is called on it, so it never fires the signal to resume the thread, causing the who system to seize up.