So, here’s a basic example that may work. I have not tested all possible values of color channels, but I tested each channel, not a number, positive and negative infinity, alpha etc, to make sure the output stays within #000000 to #FFFFFF and doesn’t throw exceptions. You may wish different behaviour for negative, positive infinity or not a number cases perhaps, but this is up to what makes sense to you. In most cases, you won’t be feeding those values into any channel anyway.
using UnityEngine;
public static class ColorTypeConverter
{
public static string ToRGBHex(Color c)
{
return string.Format("#{0:X2}{1:X2}{2:X2}", ToByte(c.r), ToByte(c.g), ToByte(c.b));
}
private static byte ToByte(float f)
{
f = Mathf.Clamp01(f);
return (byte)(f * 255);
}
}
And the tests for reference.
using NUnit.Framework;
using UnityEngine;
[TestFixture]
[Category("Type Conversion")]
internal class ColorTypeConverterTests
{
[Test]
public void ConvertsCommonColors()
{
Assert.AreEqual("#000000", ColorTypeConverter.ToRGBHex(Color.black));
Assert.AreEqual("#FFFFFF", ColorTypeConverter.ToRGBHex(Color.white));
}
[Test]
public void IgnoresAlphaChannel()
{
Assert.AreEqual("#FFFFFF", ColorTypeConverter.ToRGBHex(new Color(1, 1, 1, 0)));
Assert.AreEqual("#FFFFFF", ColorTypeConverter.ToRGBHex(new Color(1, 1, 1, 1)));
}
[Test]
public void ConvertsChannelsInRGBOrder()
{
Assert.AreEqual("#FF0000", ColorTypeConverter.ToRGBHex(Color.red));
Assert.AreEqual("#00FF00", ColorTypeConverter.ToRGBHex(Color.green));
Assert.AreEqual("#0000FF", ColorTypeConverter.ToRGBHex(Color.blue));
}
[Test]
public void ConvertsYellow()
{
UnityYellowIsKnown();
Assert.AreEqual("#FFEB04", ColorTypeConverter.ToRGBHex(Color.yellow));
}
[Test]
public void UnityYellowIsKnown()
{
// ConvertsYellow use yellow color. If Unity changes the definition of
// yellow, those tests will fail. To spare developer confusion about
// failing tests, assert that the channels are known. Because the channels
// are so arbitrary, it's also nice to see the floats in plain text.
Assert.AreEqual(1, Color.yellow.r, "Color.yellow.r changed");
Assert.AreEqual(0.921568632f, Color.yellow.g, "Color.yellow.g changed");
Assert.AreEqual(0.0156862754f, Color.yellow.b, "Color.yellow.b changed");
}
[Test]
public void ClampsChannelsBetweenZeroAndOne()
{
Assert.AreEqual("#FFFFFF", ColorTypeConverter.ToRGBHex(PosInf()));
Assert.AreEqual("#FFFFFF", ColorTypeConverter.ToRGBHex(Fill(1.5f)));
Assert.AreEqual("#FFFFFF", ColorTypeConverter.ToRGBHex(Fill(1)));
Assert.AreEqual("#000000", ColorTypeConverter.ToRGBHex(Fill(0)));
Assert.AreEqual("#000000", ColorTypeConverter.ToRGBHex(Fill(-0.5f)));
Assert.AreEqual("#000000", ColorTypeConverter.ToRGBHex(NegInf()));
}
[Test]
public void NotANumberConvertsToBlack()
{
Assert.AreEqual("#000000", ColorTypeConverter.ToRGBHex(NaN()));
}
private static Color NaN()
{
return Fill(float.NaN);
}
private static Color NegInf()
{
return Fill(float.NegativeInfinity);
}
private static Color PosInf()
{
return Fill(float.PositiveInfinity);
}
private static Color Fill(float c)
{
return new Color(c, c, c, c);
}
}
To be exact:
– PizzaProgramColorUtility.ToHtmlStringRGBA( myColor )RGBA ... not just RGB :)Thanks a lot!
– mrCrushLooked everywhere and all I've been seeing is confusing methods, formulas and conversions. You're a life saver, thank you!
– ZengonAbsolutely the best answer there is. Still up to date, and the cleanest way of doing this.
– anon43349482well, unfortunately, what you're asking for is not trivial. It looks as though they are using some kind of beam effect, and is slow dying. If you make the gameobject create the particle effect while its attached to the tip of your ray cast, it should work... this is all theory though.
– BumblingWlzard