How can I compare two Color3 inputs?

Hi. It’s me again. Currently I am trying to make a game, similar to poly bridge. I made a system, which actually works good with only 1 segment, but it fails when there are 2 segments.

This is my code with some explanation added.

script.Parent.ProximityPrompt.Triggered:Connect(function(player)
	local Player_Data = player:FindFirstChild('Player_Data')
	local PickedUpTrack = Player_Data:WaitForChild('PickedupTrack')
	local FinalPlacement = script.Parent.FinalPlacement
	
	if Player_Data and PickedUpTrack then
		for i, v in ipairs(game.Workspace.PlacementLocations:GetChildren()) do
			warn('Getting Data for Track')
			warn('Name: '..v.Name)
			warn('Selection Box Color: '..tostring(v.SelectionBox.Color3))
			warn('Local Selection Box Color: '..tostring(Color3.fromRGB(script.Parent.SelectionBox.Color3)))
			if Color3.fromRGB(v.SelectionBox.Color3) == Color3.fromRGB(script.Parent.SelectionBox.Color3) then -- This works good, but when this gets activated from the Black Segment, the black segment goes together with the Red Placement Location, which shouldn't.
				print(v.Name..' is the correct piece.')
				FinalPlacement.Value = v
			else
				return
			end
		end
		
		script.Parent.SelectionBox.Adornee = nil
		script.Parent.Transparency = 1
		script.Parent.CanCollide = false
		PickedUpTrack.Value = true
		script.Parent.ProximityPrompt.Enabled = false
		local Clone = script.Parent:Clone()
		Clone.Parent = PickedUpTrack:WaitForChild('Track')
	end
end)

I do not know, if I should compare the values with the Color3.fromRGB or not. Alternatively, you can help me fixing the black-red problem.

Please note that the red track segment and the black one have the same scripts inside them.

1 Like

The tricky thing about comparing Color3 values is that they use floating point numbers for their channels. Floating point values are lossy, so you can’t always reliably compare them by value.

There are several approaches you can take to this. Here’s a quick simple one.

local function areColorsEqual(colorA, colorB, epsilon)
	local epsilon = epsilon or 0.001
	
	if math.abs(colorA.R - colorB.R) > epsilon then
		return false
	end
	
	if math.abs(colorA.G - colorB.G) > epsilon then
		return false
	end
	
	if math.abs(colorA.B - colorB.B) > epsilon then
		return false
	end
	
	return true
end

Would be handy if Roblox had a built-in function for comparing colors, but alas.

14 Likes

So Roblox gives back the original values which are lua number which is a double hence less lossy? Does it like keep them in the background for when you retrieve one of the properties of a Color3?

Why don’t Roblox just use a 8-bit integer to store each RGB channel instead of a floating point value? Is it for simplicity or is it for saving storage?

1 Like

It’s just a weird decision they made very early on (i.e. 2005/2006) and they have to stay backwards compatible with it now.

Many of Roblox’s foundational data-types were directly inherited from Morgan McGuire’s G3D Innovation Engine.

A fairly decent chunk of the code here is still in use today.

5 Likes