For the C64 version of Bounder, the text colour of the start and end tiles bounces between black and white.
I wanted to replicate this in my version – But I wasn’t sure how.
I eventually worked through six potential implementations;
- Colour Lerp.
- HBSC
- Palette Swap
- Quad Cut-Out
- Shader
- Texture Sheet Animation.
This post covers the first three attempts;
- Colour Lerp.
- HBSC
- Palette Swap
The next post will expand on the final three.
- Quad Cut-Out
- Shader
- Texture Sheet Animation.
1. Colour Lerp
The most straight forward approach; it uses the built in method color.lerp alongside Mathf.PingPong to bounce colours between black & white – The result is applied to the start/end textures.
How this works…
The Color lerpedColor holds the colour to be displayed.
public Color lerpedColor = Color.white;
Every loop, color.lerp is used to calculate the current colour – Mathf.PingPong ‘animates’ the colour – bouncing it between (in this case) black & white.
lerpedColor = Color.Lerp(Color.white, Color.black, Mathf.PingPong(Time.time, 1)); GetComponent().material.color = lerpedColor;
The end results look great; but unsurprisingly the entire texture changes colour, not just the text.
2. HBSC
Using the HSBColor class, provided in the Unity3D wiki.
The wiki description explains that HSBColor ‘provides a Hue/Saturation/Brightness/Alpha color model in addition to Unity’s built in Red/Green/Blue/Alpha colors. It is useful for interpolating between colors in a more pleasing fashion‘
Rather than following their usage/setup instructions, I instead just stripped the [System.Serializable] tag & used the code like a standard class.
How this works…
Define a global HSBColor object.
public float time = 2.0f; private HSBColor hsbc;
Which is initialized in the start method.
hsbc = HSBColor.FromColor(color);
Then, every loop the next colour to display is calculated (I think it rotates through six different colours)
hsbc.h = (hsbc.h + Time.deltaTime / time) % 1.0f; GetComponent().material.color = HSBColor.ToColor(hsbc);
The result may give you a headache;
3. Palette Swap
This reuses the Palette Swap code I wrote for the Spectrum tiles – I really like the effect – (Though I’d need to figure out why some white pixels have turned yellow when being displayed). I’d expected a huge performance hit with this method, but when tested, the game ran at a good pace.
How this works…
Each tile prefab has a material component attached. Each material component has a texture attached. This is the texture used when drawing the tile to screen.
Since the intention is to change the colours of the materials texture, the script keeps a master copy that is unaffected by the paletteSwap code – paletteSwap code uses this master copy as a reference every loop/colour update.
(Rather than using a reference textures; the script could instead, store a copy of the last colour applied and pass that to the paletteSwap code to change every loop – Unfortunately the banner letters lerp between black and white – & the texture has some black pixels in place which may accidently get caught up in the animation).
First the script defines a global texture to be used to hold the master/base texture;
Texture2D paletteSwapTexture;
A copy of this texture is assigned to paletteSwapTexture – (I’m guessing it’s a copy and not a reference, since changing the colours in rend.material.maintexture has no effect on the contents of paletteSwapTexture)
rend = GetComponent(); paletteSwapTexture = (Texture2D) rend.material.mainTexture;
The ‘toColour‘ colour array is defined – This is used to identify which colour in the texture to look for (index 0) & what colour to change it to (index 1).
Color[] toColour = new Color[2] { Color.white, Color.white };
Then, every loop ‘Colour Lerp’ (& Mathf.PingPong) calculates the next colour to display – This is then passed to the PaletteSwap method.
toColour[1] = Color.Lerp(Color.white, Color.black, Mathf.PingPong(Time.time, 1)); Renderer rend = GetComponent(); rend.material.mainTexture = PaletteSwap(toColour, paletteSwapTexture);
Which swaps the colours and returns a new Start/Goal tile texture;
Texture PaletteSwap(Color[] toColours, Texture2D inTexture) { Texture2D source = inTexture; Texture2D destination = new Texture2D(source.width, source.height); //--- Color[] pixels = source.GetPixels(0, 0, source.width, source.height); int pixelsLength = pixels.Length; for (int counter = 0; counter = 0.98 && pixels[counter].g >= 0.99) pixels[counter] = toColours[1]; } destination.SetPixels(0, 0, destination.width, destination.height, pixels); destination.Apply(); //--- return (Texture)destination; //--- }
Which ultimatly looks like this – Nice effect, pain in the arse yellow pixels;
Next post: 2.5a Palette Shift
Last post: 2.4 Edge Padding
One Reply to “Adventures in Unity – 2.5a Palette Shift”