How do i make a part change its color depending on velocity?

i’m making this script where a part is blue when it is not moving, and changes color when it moves, which the color will turn red when it is moving fastest. i am doing this to check out some physics stuff, so it involves multiple models (all named Model), and it will detect each part that moves and change its color accordingly.

i tried to write my own script but it only changes the part models to blue, but it never changes even when i see multiple parts moving.

here is the script i attempted

    repeat
    	for i,v in pairs(workspace:GetDescendants()) do
    		if v.Parent.Name == "Model" then
    			local Veloc = v.Velocity.magnitude
    				if Veloc >= 0.5 then
    					v.Color = Color3.fromRGB(0,0,255)
    			elseif Veloc >= 1 then
    					v.Color = Color3.fromRGB(0,200,200)
    			elseif Veloc >= 3 then
    					v.Color = Color3.fromRGB(0,255,180)
    			elseif Veloc >= 5  then
    					v.Color = Color3.fromRGB(0,255,0)
    			elseif Veloc >= 8  then
    					v.Color = Color3.fromRGB(255,200,0)
    			elseif Veloc >= 10  then
    					v.Color = Color3.fromRGB(255,150,0)
    			elseif Veloc >= 15  then
    					v.Color = Color3.fromRGB(255,0,0)
    				end
    			end
    	end
    	wait(0.025)
    until false 

is there a way i can improve this terrible coding?

1 Like

Maybe you could do something like this:

local PartVelocity = workspace.Part.Velocity
local ColorPart = workspace.ColorPart
local ClampedVelocity = math.clamp(PartVelocity / 15, 0, 1)

ColorPart.Color = Color3.fromHSV(ClampedVelocity, 1, 1)

-- If you want to invert the colors
ColorPart.Color = Color3.fromHSV(1 - ClampedVelocity, 1, 1)

but ColorPart is a different object, i want the part itself to change colors and not change another part’s colors. i tried to work around this though by changing some parts of the code to work with the model, but it still will not work.

repeat
	for i,v in pairs(workspace:GetDescendants()) do
		if v.Parent.Name == "Model" then
			local PartVelocity = v.Velocity
			local ColorPart = v
			local ClampedVelocity = math.clamp(PartVelocity / 15, 0, 1)

			ColorPart.Color = Color3.fromHSV(ClampedVelocity, 1, 1)
		end
	end
	wait(0.025)
until false

the output error also states

Workspace.Script:6: invalid argument #1 to 'clamp' (number expected, got Vector3)

This should work.

local RunService = game:GetService("RunService")

local part = script.Parent
local velocity_colour_red = 200 -- At this velocity colour will be fully red

local colour_red = Vector3.new(255, 0, 0) -- (In Vector form)
local colour_blue = Vector3.new(0, 0, 255) -- (In Vector form)

while true do
	local velocity = part.AssemblyLinearVelocity
	
	local alpha = math.min(velocity.Magnitude / velocity_colour_red, 1)
	local colour = colour_blue:Lerp(colour_red, alpha)
	
	part.Color = Color3.fromRGB(colour.X, colour.Y, colour.Z)
	
	RunService.Stepped:Wait()
	RunService.Stepped:Wait()
end

i applied this to a single part and it worked. but how do i implement this for multiple parts within a model? i tried using a for loop just like the one in the main post but it did not work. the output log also didnt show any errors

local RunService = game:GetService("RunService")

local model = workspace.Model
local velocity_colour_red = 200 -- At this velocity colour will be fully red

local colour_red = Vector3.new(255, 0, 0) -- (In Vector form)
local colour_blue = Vector3.new(0, 0, 255) -- (In Vector form)

local children = model:GetDescendants()
local n_children = #children

while true do
	for index = 1, n_children do
		local object = children[index]
		
		if (not object:IsA("BasePart")) then continue end
		
		local velocity = object.AssemblyLinearVelocity

		local alpha = math.min(velocity.Magnitude / velocity_colour_red, 1)
		local colour = colour_blue:Lerp(colour_red, alpha)

		object.Color = Color3.fromRGB(colour.X, colour.Y, colour.Z)
	end
	
	-- Wait for fairly long time to avoid possible performance issues
	RunService.Stepped:Wait()
	RunService.Stepped:Wait()
	RunService.Stepped:Wait()
	RunService.Stepped:Wait()
end

it finally works now thank you!