How would I make a renderstepped color-changing part that included playback loudness?

hey! im trying to create something like the video above. (cant hear audio with gyazo gif but its using playbackloudness to match with the audio.)

i have a script that does this but with the height/width of the object, how would i do it with color? the script has a color part, but it doesnt use renderstepped so its either one color or the other. tell me if u wanna see the script and ill reply w it

1 Like

That’s a neon material and the “bloom” effect depends on the brightness/value of the color which you can interpolate
Note that in interpolation, the alpha value needs to be normalized into the interval [0, 1]

You could:

  • Interpolate between the set color and black
    --init
    local setColor = Color3.fromRGB(100, 200, 255) --example
    local clr_black = Color3.new()
    
    --inside renderstepped
    local alpha = .5 --0 is minimum volume, 1 is max
    local color = clr_black:Lerp(setColor, alpha)
    
  • Use the HSV constructor
    --init
    local setColor = {.25, 1} --hue and saturation respectively
    
    --inside renderstepped
    local alpha = .5 --0 is minimum volume, 1 is max
    local color = Color3.fromHSV(unpack(setColor), alpha)
    

wait so im kinda confused, where do i actually plug in the part? also what does init mean

You define the part somewhere and just change the color
Example:

local part = workspace:WaitForChild('Sign')

part.Color = ...--something

“init” means initialization, it’s just there to tell you that that portion of the script should be outside and at the top of the script (it initializes the rest of the script)

1 Like

ohh alright, so if i do a color3.new, what does the “local setColor = Color3.fromRGB(100, 200, 255)” do? does that hold the same function

Color3.fromRGB functions similarly as Color3.new, they both create a new Color3 instance, it’s just that they’re created differently

Color3.fromRGB accepts RGB values (numbers in the range 0 to 255) while Color3.new accepts only normalized numbers (0 to 1)

ohh okay makes sense, while i try to mess with this script i have a quick semi-related question that you may or may not be able to answer. is there any way to identify in a variable the current playing sound? for example, i have the line below which just identifies one sound but i want to make it so that it identifies the current playing song which is randomized through a table in another script.

local loudness = game.Workspace.Sound.PlaybackLoudness

You could use Bindable Events/Functions to identify whichever song is playing. Put the listener inside the script that changes the color, and have the song rotation system fire the event.
https://developer.roblox.com/en-us/api-reference/class/BindableEvent

this is a little confusing im trying to do this between scripts but i dont think im doing it correctly and i dont know what to do put in the events.

You have the API reference I linked. You could also look elsewhere for tutorials on bindable events

yeah ive been trying to watch tutorials however im just not too sure what to put in the listener script for example:

	
	local layla = game.ReplicatedStorage.Layla
	
	layla.Event:Connect(function(onEvent)
		
	local loudness = game.Workspace.Sound.PlaybackLoudness

i have this in the listener script but im not sure what to do with the playback loudness


sounds[math.random(1, #sounds)]:Play()

end

layla:Fire(onEvent())

heres the fire script if you need it

1 Like

You could alternatively use the global table _G instead of bindable events if you think that’s simpler. It’s a table that is shared by all scripts in the same execution level, meaning that its internals can be accessed and modified by multiple scripts

In the song rotation script, you can toss the playing sound instance into _G:

--just an example
function playRandomSong()
  local song = sounds[math.random(#sounds)]
  song:Play()
  _G.PlayingSong = song --put the song in the _G table
end

And in the color-changing script, you will use that song accordingly:

--just an example
local res = game:GetService('RunService')
local part = workspace:WaitForChild('something')
local setColor = Color3.fromRGB()
local clr_black = Color3.new() --empty constructor means black

res.RenderStepped:Connect(function()
  local song = _G.PlayingSong
  if song and song.IsPlaying then --make sure there's actually a song playing first
    local alpha = song.PlaybackLoudness * .001 --divide by 1000 to normalize the number since PlaybackLoudness is a number ranging from 0 to 1000
    part.Color = clr_black:Lerp(setColor, alpha)
  end
end)

Note that _G does not replicate between clients and the server

1 Like

okay so since it doesnt go through client to server or vise versa, could i put the color change script in a reg script?

yes, but do note that RenderStepped doesn’t exist on the server and you will have to change it to either .Stepped or .Heartbeat

Ideally, for optimization reasons, you should be changing the part’s color on the client as doing it on the server might overload the replication system and make your game laggy
So sometime in the future when you do learn how to use remote events, you should swap it over, but for now it should work fine

alright! changed it to heartbeat. i added the _G thing into my music script and now the music isnt playing at all, let alone being randomized. did i do something wrong?

local baba = MUSIC:GetChildren()
local layla = game.ReplicatedStorage.Layla
local sounds = {
	
	MUSIC:WaitForChild("DiamondAndPearl"),
	MUSIC:WaitForChild("AdoreYouHarryStyles")
	
	
	
	
}


function playRandomSong()
	local song = sounds[math.random(1, #sounds)]:Play()
	_G.PlayingSong = song
end

What you’re doing here is wrong. You need to run :Play() separately

local song = sounds[math.random(#sounds)]
song:Play()
_G.PlayingSong = song

This is because by putting :Play() on the same line, Lua will now assign whatever :Play() returns to the variable song, and not the song itself

i tried and it still doesnt work, not sure why.

Did you even run the playRandomSong function?

oh whoops hold on lol idk how i forgot to do that

okay im running it and it works, and the part turned black however it isnt color changing.

i added a color to the setcolor variable like so:

local part = workspace:WaitForChild('TRIAGE')
local setColor = Color3.fromRGB(75, 43, 255)
local clr_black = Color3.new()