Adventures in Unity – 2.8 Tileset C64


Below is a (hopefully) complete list of tiles used in the C64 version of Bounder.
Both foreground & background (floor) tiles are included.

Default Tiles

00 - Standard
Type: Standard Floor Tiles
Levels: All
Effect: Safe tile – player bounces off

01 - Corners
Type: Standard Floor Tiles (Corners)
Levels: All
Effect: Safe tile – player bounces off

Effect Tiles

02a Effects C64 - Mystery
Type: Mystery
Levels: All
Effect:  Mystery tiles are activated if the player bounces on them.

They can provide either positive or negative effects.

However, the way mystery tiles are handled on the C64 version of Bounder adds a slight random/strategic element to the game…

Each mystery tile has a specific effect assigned to it – It will have the same effect every game.

When a mystery tile is created, its effect, rather than being attached to the tile,  is instead added to a global list.

So – If the current game screen contains three active mystery tiles, the list will contain three effects.

No matter which tile the player bonuses on, the first effect in the list will be applied to the player.

Once the effect has been applied to the player, it is removed from the list – Otherwise, it is removed from the list once the mystery tile scrolls offscreen.

List Of Potential Effects:
1 bonus level jump
2 bonus level jumps
5 bonus level jumps
20 bonus level jumps

Minus 10 bonus level jumps

1 extra life
2 extra lives

Instant death – dart
Instant death – mouth
Instant death – player explodes

200 bonus points
500 bonus points
1000 bonus points
2000 bonus points
5000 bonus points
7000 bonus points
10000 bonus points
30000 bonus points
50000 bonus points

02a Effects C64 - LongJump
Type: Long Jump
Levels: All
Effect: Allows the player to jump twice as far

02a Effects C64 - Vanishing
Type: Vanishing
Levels: 5 6
Effect: Disappears just before player collision

Instant Death Tiles

07b - Grass
Type: Grass
Levels: 1 7 (Green), 10 (Yellow), 6 (Blue)
Effect: Player can safely bounce on basic grass (single colour tile, far left column) – All others kill the player on contact

09b - Lava1
Type: Lava (Type 1)
Levels: 2 4 9 (Orange), 5 (Blue), 8 (Purple), 10 (Yellow)
Effect: Kills the player on contact

09c - Lava2
Type: Lava (Type 2)
Levels: 2 4 9 (Orange), 1 (Green), 5 (Blue), 8 (Purple), 10 (Yellow)
Effect: Kills the player on contact

09d - Lava3
Type: Lava (Type 3)
Levels: 4 9 (Orange), 5 (Blue), 8 (Purple), 10 (Yellow)
Effect: Kills the player on contact

06b - Mud
Type: Mud (Type 1)
Levels: All
Effect: Kills the player on contact

05b - Mud2
Type: Mud (Type 2)
Levels: 3 5 6 7 8 9 10
Effect: Kills the player on contact

03b - Water
Type: Water
Levels: 3 5 6
Effect: Kills the player on contact

03b - Quicksand
Type: QuickSand (Water Yellow)
Levels: 10
Effect: Kills the player on contact

Background/Floor Tiles

08b - Floor
Type: Floor
Levels: All – 1 7 (Green), 2 4 9 (Orange), 3 5 6 (Blue), 8 (Purple), 10 (Yellow)
Effect: Kills the player on contact

Play the game (WebGL)

Next Post: 2.9 Tileset Spectrum

Last post: 2.7 Mesh Fade

Contents page.



Adventures in Unity – 2.7 Mesh Fade


Fading a model out of the game can be a pretty useful technique.

When using the built-in shaders, fading a single mesh model in/out is a pretty straight forward process.

If you have model made up of multiple meshes – there is a couple of extra steps you may need to get the desired effect.

I’m going to try and cover both situations below;

For this example, I’m using Unity’s built-in ‘standard’ shader.

The standard shader provides two rendering modes that can be used to fade a mesh – Transparent & Fade.

The unity guide explains their intended usage;

TransparentSuitable for rendering realistic transparent materials such as clear plastic or glass. In this mode, the material itself will take on transparency values (based on the texture’s alpha channel and the alpha of the tint colour), however reflections and lighting highlights will remain visible at full clarity as is the case with real transparent materials.

FadeAllows the transparency values to entirely fade an object out, including any specular highlights or reflections it may have. This mode is useful if you want to animate an object fading in or out. It is not suitable for rendering realistic transparent materials such as clear plastic or glass because the reflections and highlights will also be faded out.

Though it’s generally best to try out both options and see which works best for your project.

To fade in/out a single mesh model;

Models use a material to manage their texture, each material has an assoiated colour.
To fade the mesh we change of the alpha value of this colour.

Alpha values are between 0 & 1;
0.0 = completely transparent
0.x = faded to some degree.
1.0 = fully opaque

To fade a mesh out by 50% (In a script attached to the model’s prefab);

Renderer renderer = GetComponent();
Color color = renderer.material.color;
color.a = 0.5f;
renderer.material.color = color;

to fade a specific colour in the material, use the SetColor function;

Renderer renderer = GetComponent();
Color color = renderer.material.color;
color.a = 0.5f;
renderer.material.SetColor("_Color", color);
Single mesh model – Standard shader set to Fade
Single Mesh Model – Standard shader set to Transparent

To fade in/out a multi-mesh mesh model;

If the model has multiple meshes, we need to reference the material(s) for each mesh.

(It can be useful to create an instance of each material.
That way the alpha change will only effect that instance of the model & not every model that uses the material)

We may also need to manually set the models ZWrite value
The ZWrite value determines the order in which each mesh is drawn to screen.

Multi-Mesh model – Standard Shader set to Fade – Default ZWrite order
Multi-Mesh model – Standard shader set to Transparent – Default ZWrite order

To put this in code (as a script attached to the models prefab);

First create a global variable to hold the renderer for each mesh;

Renderer[] rendererObjects;

Then in the init or start method, the renderer array is initialised & populated,
the ZWrite value (draw order) is defined (rather simply here)

 for (int counter = 0; counter < rendererObjects.Length; counter++)
   Material material = rendererObjects[counter].material;
   material.SetInt("_ZWrite", counter);

Once thats done & we are ready to fade – In the main code we can fade the model in or out (in this example I fade the model out – then destroy the instance once it is completely transparent);

for (int counter = 0; counter < rendererObjects.Length; counter++)

   Color color = rendererObjects[counter].material.color;
   color.a -= (Time.deltaTime / 1f) % 1.0f;

   if (color.a <= 0)

      rendererObjects[counter].material.SetColor("_Color", color);


The final result should look something like this;

Multi-mesh model – Standard shader set to Fade – ZWrite manually defined.
Multi-Mesh model – Standard shader set to Transparent – ZWrite manually defined.

Play the game (WebGL)

Next Post: 2.8 Tileset C64

Last post: 2.6 Pause & Resume

Contents page.

Adventures in Unity – 2.6 Pause & Resume


Whenever a bonus is collected a message box is displayed and the game pauses momentarily.

It’s not a function of the game I particularly like; and I probably wouldn’t use it in the final release – But, since the point of this project is to try things out & help me learn Unity, I figured I’d try and replicate it anyway.


When displaying the message box, the entire game should pause – including problematic functions like particles/physics/etc.. things controlled by the Unity engine.

Google found me a solution pretty quickly – Time.timeScale

To freeze the game set Time.timeScale = 0 – To resume the game set Time.timeScale = 1.

Time.timeScale is a float variable.
Every loop, Unity multiplies Time.deltaTime against Time.timeScale.
This determines the speed of the game – For anything that references Time.deltaTime – Any update that doesn’t reference Time.deltaTime will be unaffected (Though you really should be using Time.deltaTime).

It’s usually used to pause games & tends to be set with values 0 or 1.
Though it can be used to dynamically slow/speed up gameplay – values higher than 1 may legally require that yakety sax be played at all times.

With everything paused; the next problem was how to animate the message box – (fade in, display for x seconds, fade out).

I can run the animation without using Time.DeltaTime – But then I won’t receive any of the benefits.

Another quick google search identified the solution – A homebrew Time.deltaTime using replacement using Time.realtimeSinceStartup.

Unity documentation explains ‘realtimeSinceStartup returns the time since startup, not affected by Time.timeScale. realtimeSinceStartup also keeps increasing while the player is paused (in the background). Using realtimeSinceStartup is useful when you want to pause the game by setting Time.timeScale to zero, but still want to be able to measure time somehow.

I use The replacement Time.deltaTime as a timer;

  IEnumerator PauseTimer(float delay)

     float start = Time.realtimeSinceStartup;
     timerComplete = false;

     while (Time.realtimeSinceStartup < start + delay)
          yield return null;

     timerComplete = true;



Play the game (WebGL)

Next Post: 2.7 Mesh Fade

Last post: 2.5b Palette Shift

Contents page.

Adventures in Unity – 2.5b Palette Shift


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.

The first three implementations, were covered in the last post.

  • Colour Lerp.
  • HBSC
  • Palette Swap

This post will expand on the second half;

  • Quad Cut-Out
  • Shader
  • Texture Sheet Animation.

4. Quad Cut-Out

This method uses two textures – One ‘base’ texture displays the standard start/goal tile texture – The other ‘top’ texture; is a copy of the top face of the tile texture; the face showing the start/goal banner image & text – with everything except the letters (start & goal) removed (transparent instead).

Left image shows the base tile texture.
Right image shows the quad texture for the same tile.

The base texture is used to draw the tile model. The top texture is applied to a quad – a child of the tile – which is positioned just over the top of the base tile.

The colour lerp code is then applied to the the top texture – ensuring only the text changes colour while the background remains the same.

How this works…

First a quad (this will be created locally) and a material holding the quads texture (this will be passed as a reference in the Unity editor) are defined as global variables;

GameObject quad;
public Material material1;

In start, the quad is created & configured.

if (type == Type.Enter || type == Type.Exit)

     quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
     rend = quad.GetComponent();
     rend.material = material1;
     quad.transform.parent = transform;
      quad.transform.Rotate(90, 0, 0);


Since this method uses the colour lerp code, we need somewhere to hold the current colour.

public Color lerpedColor = Color.white;

Then every loop, the position of the quad is updated (to keep up with the tile as it scrolls down the screen). The next colour for the banner flash is calculated and assigned to the quads texture.

quad.transform.position = new Vector3(transform.position.x, transform.position.y + 0.275f, transform.position.z);
lerpedColor = Color.Lerp(Color.white,, Mathf.PingPong(Time.time, 1));
quad.GetComponent().material.color = lerpedColor;

This works well, but it does require a quad to be created (another draw call per loop), as well as an extra texture (more work & extra complications)  – Neither is a big issue, but it’s more complications than I think should be required.

I think the result looks fine, though I suspect it would look much better if I’d removed the text from the base texture – As it is, the base text seems to interfere – giving a slight glow – behind the flashing letters of the quads texture.


5. Shader

The original version of the shader, I  checked the colour of the current _MainTex pixel – & changed any which were white. This worked horribly – It seems that before I got to the texture it has been already modified somewhere along the pipeline.


Instead I take a more long-winded approach.

How this works…

Alongside the auto-generated input variables (_Color, _MainTex, _Glossiness & _Metallic – all generated by Unity when creating the shader).

The custom input variables are added;
_Color1 – Used to set the start colour in the loop (white)
_Color2 – Used to set the start colour in the loop (black)
_CutOutTex – From the Quad Cut-Out method, this is a copy of _MainTex, but with everything except the letters (start & goal) removed (transparent instead).

Left image shows _MainTex.
Right side shows _CutOutTex

In the surf method, after the colour of the _MainTex is sampled, the equivalent colour from _CutOutTex is identified.

If the alpha values of the sampled _CutOutTex colour is > 0 (not transparent) – Then this is a letter (in the start/goal banner) which needs to be colour shifted – The current colour shift colour is calculated and drawn to the screen.

If the alpha values from the _CutOutTex colour is <= 0 (transparent) – Then this is not part of the banner text and the sample from _MainTex (the default banner texture) is drawn..

Shader "Custom/NewSurfaceShader" {
     Properties {
          _Color ("Color", Color) = (1,1,1,1)
          _MainTex ("Albedo (RGB)", 2D) = "white" {}
          _Glossiness ("Smoothness", Range(0,1)) = 0.5
          _Metallic ("Metallic", Range(0,1)) = 0.0
          _CutOutTex("CutOut", 2D) = "white" { }
          _Color1("Color1", Color) = (1.0, 0.0, 0.0, 1.0)
          _Color2("Color2", Color) = (0.0, 0.0, 1.0, 1.0)
          _Speed("Speed", float) = 0.2

     SubShader {
          Tags { "RenderType"="Opaque" }
          LOD 200
          // Physically based Standard lighting model, and enable shadows on all light types
          #pragma surface surf Standard fullforwardshadows

          // Use shader model 3.0 target, to get nicer looking lighting
          #pragma target 3.0

          sampler2D _MainTex;

          struct Input {
               float2 uv_MainTex;

          half _Glossiness;
          half _Metallic;
          fixed4 _Color;
          sampler2D _CutOutTex;
          uniform fixed4 _Color1;
          uniform fixed4 _Color2;
          uniform float  _Speed;

          void surf (Input IN, inout SurfaceOutputStandard o) {
          // Albedo comes from a texture tinted by color
          fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
          fixed4 c2 = tex2D(_CutOutTex, IN.uv_MainTex);

          if (c2.a > 0) {
               fixed4 c3 = lerp(_Color1, _Color2, abs(fmod(_Time.a * _Speed, 2.0) - 1.0));

               //if (c.r > 0.99 && c.g > 0.99)
                    c = (c * c3) * _Color;
                    c = c * _Color;

               o.Albedo = c.rgb;
               // Metallic and smoothness come from slider variables
               o.Metallic = _Metallic;
               o.Smoothness = _Glossiness;
               o.Alpha = c.a;

     FallBack "Diffuse"

I haven’t written anything for shaders in a number of years – last time was HLSL for XNA. So the learning curve here was for both figuring out nity & figuring out Unity’s shaders. I’m not particularly happy with the code I’ve put together – I’m very confident there ere are far more succinct ways to achieve the same result – But the the animation looks okay.


6. Texture Sheet Animation.

This is the method I’ve decided to use – It works almost like a traditional animation/flip book – using a series of images, each slightly different from the next – so when they are swapped a speed they appear to show movement.

In this case, the models texture is split into a grid – Each cell of the grid contains a frame of the animation (in this case 8 frames are used).
The model is drawn referencing one cell of the grid\one frame of the animation (UV mapping is explained badly in my last post).
Code (either a Unity script or shader) is used as a timer – to determine when to change to the next frame.

Animation texture – With individual frames/cells highlighted.

For the code, I referenced Unity3D wiki – Animating Tiled texture
The page offers six code examples – one java/five C#

I had the most success using AnimateTiledTexture & AnimateSpriteSheet classes
Setting with the AnimateTiledTexture code because it was the easiest for me to tweak in order for it to animate the way I needed…
The goal/start texture have frames from white to black – I use ping-pong setup to run backwards and forward through the animation frames – from white to black, then in reverse from black to white – halving the final texture size.

With the code in place I needed to configure the assets – This was much harder to setup than expected – which, for a modern 3D gaming environment was a little disappointing – setting up was more guess work than design – I found it is far easier to setup an animated texture in (the ten year old) XNA.

With first attempt – I made the mistake of using a non-power or two sized texture – This resulted in animated tiles which were blurry, and jitter – jumping around as it forced through each frame – It looked pretty horrible


The image quality improved after resizing the texture to a power of two
and (in the textures Material settings) defining the ‘Tiling’ values to match the frame size
(8 frames in total – 4 columns, 2 rows – Tiling X = 0.25 Y = 0.5 )

This produced a noticeably sharper – non-jittery texture – but displayed a lot of artifacts.
I tried changing the text import settings to advanced; turning off mipmaps, mapping, etc… anything that could be turned off was turnd off – setting the wrap mode to clamp, filter to point – none of which had any effect.

What ultimatly worked for me was setting the texture type to cursor.
I have no idea why cursor settings resolve the issue – or if the next update will break it & put me back to square one.
But for now I have nice, clean, sharp animated start/goals tiles


Play the game (WebGL)

Next post: 2.6 Pause & Resume

Last post: 2.4 Edge Padding

Contents page.

Adventures in Unity – 2.5a Palette Shift



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;

  1. Colour Lerp.
  2. HBSC
  3. Palette Swap
  4. Quad Cut-Out
  5. Shader
  6. 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,, 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.






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,, 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);


     return (Texture)destination;



Which ultimatly looks like this – Nice effect, pain in the arse yellow pixels;



Play the game (WebGL)


Next post: 2.5a Palette Shift

Last post: 2.4 Edge Padding

Contents page.



Adventures in Unity – 2.4 Edge Padding


The levels in this project are made up of tiles – I’d working with about four different tile types to when constructing the basic game framework;


1. Default Floor Tile
2. Bonus Tile
3. Start Tile
4. Goal Tile


The floor tiles looked great – But the start, goal & bonus tiles were a little out of place & had seams showing;




Googling around, I discovered I wasn’t the first person to have this issue – & everyone seems to have their own resolution…

Some people offered sensible first steps advice, such as ensuring the in the texture setting clamp rather than repeat was selected – Others suggesting ideas like merging the tiles into one model, drawing with a custom shader, deleting all offscreen model faces, recalculating the models normals, turning off anti aliasing, turning off mip-mapping, etc..

After trying, a failing with quite a range potential solutions; what eventually worked for me was edge padding.

Edge padding, as the Unity docs explain;
Unity renders a scene using a process known as downsampling which uses texture filtering to smoothly render the textures. If the ‘gutters’ (blank areas between UV’s) have colors/transparencies that are very different from the colors inside the UV’d areas, then those colors can ‘bleed’ together which creates seams on the model. This problem will also occur when neighbouring UV shells have different colors; as the texture is downsampled eventually those colors start to mix.

To avoid this problem, edge padding should be added to the empty spaces around each UV shell. Edge padding is the process of dilating the pixels along the inside of the UV edge to spread the colors outward, forming a border of similar colors around the UV shell.



UV Mapping is the process of projecting a texture onto a 3D object – It identifies what area in a texture/image a model faces uses as it’s texture.

So, for example, in the image below the right side shows a model with one face selected (outlined in orange & shaded slightly) .

The left hand side shows the texture being used – The orange square (on the top left quarter) shows what part of the texture will be used to ‘paint’ the select face

UV Mapping 2



In my case, my original textures looked like this;


My uv texture mapping looked like this;


The problem was the UV areas I’d setup were too tight – so when Unity rendered the textures onto the models, it would sometime collect colour information outside my defined UV area – causing seams to be displayed.

The fix was to reposition the UV mapping & add a border to accommodate the potential bleeding effect.

My initial attempt at edge padding resolved 90% of the problem – but I found the enter/exit tiles didn’t quite match up.




For ‘complex’ textures, instead of continuing that edge colour, I instead just continued the pattern.

Instead of using this;


I setup the texture to look like this;


Which worked perfectly;




Note: My textures & UV mapping are pretty simple- I used that to my advantage when edge padding – padding far more of the texture than I really needed to.

The amount of padding actually required depends on the size of the texture used – (I think the smaller the texture, the higher the chance of seams)- For this game, my textures are 64×64 – I found I needed a 3-4 pixel buffer to completely remove seams.



Ultimately, edge padding provides a satisfying fix – going forward, as long as I keep padding in mind when creating textures, it should have almost no further impact on this project.


Play the game (WebGL)


Next post: 2.5b Palette Shift

Last post: 2.3 Palette Swap

Contents page.



Adventures in Unity – 2.3 Palette Swap



I wanted to try using textures based on the original games graphics.

Mainly for two reasons;

  1. Because I wanted to see how it would look – If it works out, I have some low impact textures for the WebGL version of the game – If not, then, at least I’ll still have reason #2.
  2. I thought they would work well as placeholders – until this point, I’d just coloured different tile types different colours – & while that’s fine when I only have 2-3 types, once the numbers start stacking up it’s going to get confusing remembering which tile colour has what effect – Using the original graphics as placeholder textures ensures they’ll look unique & easily distinguishable – It’ll make it faster & easier when trying to see how the original game works and feels against my implementation – & makes creating the textures much easier & far less time consuming.

However, since I never seem to like making anything too easy for myself, I decided to create textures based on both the C64 & Spectrum versions of the game.



The Sinclair ZX Spectrum 48k handled graphics in a rather ‘unique’ way- The 256×19 screen was broken down into 8×8 pixel blocks – Each block can display two colours at any one time – background & foreground (paper & pen)

While this architectural design caused lots of headaches when developing video games – With bounder, it allowed the developers to base each level on a different colour pair – so they could use the same base graphic for each tile type – But by changing the colours used to draw the tiles, it gives each level a distinct feel.

Effectively palette swapping. As Wiki explains;

A palette swap is a practice used in video games, whereby a graphic that is already used for one element is given a different palette, so it can be reused as other elements. The different palette gives the new graphic another set of colors, which makes it recognizably distinct from the original.





After a quick google I figured I had three options for replicating the spectrum level  based palette swap;

  1. Use a different texture for each level. This, given my requirements, would be the quick to implement, be low on systems resources and could be implemented cleanly.
  2. Write a shader to swap the colours at runtime – Another sensible, relatively easy option – & since I’ve yet to play around with shaders in Unity it would have been a useful intro.
  3. Edit the textures and change their colours at runtime – When I’ve tried this sort of thing in the past, it’s usually come with a huge processing overhead – impacting game performance needlessly – probably the worst option of the three.


I went for approach #3.



With this game, palette swapping is pretty straight forward;

The projects textures contains a maximum or four colours; black, white, green and blue (most only contain black & white) – e.g.


Since there are so few colours, all of which are known beforehand, identifying and swapping is pretty simple.

The code provided below is specific to this,simple colour swap – but should be easily modifiable to accommodate more complicated requirements.





First we need to make the original (source) texture read/write enabled. This is so we can run though the texture and read the colour of each pixel. This can be done within the Unity IDE in three steps.

1 In the ‘project‘ tab, select the texture you want to use;



2. In the ‘inspector‘ tab, change change the texture’s ‘Type‘ to ‘Advanced‘.



3 Next, put a tick in the read/write enabled check box.




Now the ‘source’ texture is ready, we need some code to perform the swap.

I’ve written two methods for swapping the colours -Both are displayed below – There’s not a lot between them – cut & paste whichever one you prefer.


Method 1:

Based on the code provided by Scribe in answer to a palette swap question on the unity community answers

This method requires a source texture (the read/write enabled texture created earlier) and an array of colours – These are the level specific colours which will replace the source colours.

It copies the textures pixels into a Color array – Then loops through the color array, checking the colour of each pixel and replacing as required.

Once all the colours have been checks & changed, it sets the image into the destination texture & importantly calls Apply() to save the updated texture.

Texture PaletteSwap(Texture2D source, Color[] toColours) {

     //Renderer rend = GetComponent();
     //Texture2D source = rend.material.mainTexture 

     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< pixelsLength; counter++)

          if (pixels[counter] == Color.white)
               pixels[counter] = toColours[0];

          else if (pixels[counter] ==
               pixels[counter] = toColours[1];

          else if (pixels[counter] ==
               pixels[counter] =;

          else if (pixels[counter] ==
               pixels[counter] = toColours[2];


     destination.SetPixels(0, 0, destination.width, destination.height, pixels);


     //rend.material.mainTexture = (Texture)CopyTexture2D((Texture2D)rend.material.mainTexture);
     return (Texture)destination;




Method 2:

Based on code provided by CarterG81 in answer to a palette swap question on the unity community forums

This method uses two while loops (y & x)  to get the coordinates of each pixel in the source texture in turn – It then checks the retrieved pixels colour against the swap list – writing the replacement colour directly onto the destination texture.

Once the loops complete, it calls the all important Apply() method to create the new destination texture.

Texture PaletteSwap(Texture2D source, Color[] toColours)

     //Renderer rend = GetComponent();
     //Texture2D source = rend.material.mainTexture 
     Texture2D destination = new Texture2D(source.width, source.height);

     Color pixelColor;

     int y = 0;
     while (y < destination.height)

          int x = 0;
          while (x < destination.width)

               pixelColor = source.GetPixel(x, y);

               if (pixelColor  == Color.white)
                    destination.SetPixel(x, y, toColours[0]);

               else if (pixelColor  ==
                    destination.SetPixel(x, y, toColours[1]);

               else if (pixelColor  ==
                    destination.SetPixel(x, y,;

               else if (pixelColor  ==
                    destination.SetPixel(x, y, toColours[2]);

                    Debug.Log("Color.r: " + source.GetPixel(x, y).r + "  Color.g: " + source.GetPixel(x, y).g + "  Color.b: " + source.GetPixel(x, y).b);






     //Apply the texture to the material
     //rend.material.mainTexture = (Texture)CopyTexture2D((Texture2D)rend.material.mainTexture);
     return destination;



The colour swap list is defined in a cheesy little method which, when passed the current level number, returns a array colors for that level;


Color[] LevelColours(int inLevel)
     switch (inLevel)
          case 1: return new Color[] { Color.white,, Color.magenta };
          case 2: return new Color[] { Color.yellow,, Color.magenta };
          case 3: return new Color[] { Color.cyan,, Color.cyan };
          case 4: return new Color[] { Color.cyan,, };
          case 5: return new Color[] {,,Color.white };
          case 6: return new Color[] { Color.white,, };
          case 7: return new Color[] { Color.yellow,, Color.white };
          case 8: return new Color[] { Color.white,, Color.yellow };
          case 9: return new Color[] { Color.yellow,, Color.white };
          case 0: return new Color[] { Color.cyan,, };
          default: return new Color[] {, Color.yellow, Color.white };





& that’s it.

I’m currently swapping the texture palette every time I instantiate a new tile – & while It seems to work with no noticeably slowdown/jerkiness, it’s impractical as a long term solution.

My next step will be to instantiate everything at the beginning of the level…

  1. Once the level data is loaded, identify which tile types will be used for the level,.
  2. Load the the textures for the identified tile types – change their colours and store in an object.
  3. Now, when instantiating a new tile instance, I attach the relevant pre-cooked texture.


Play the game (WebGL)


Next post: 2.3 Edge Padding

Last post: 2.2 Framework

Contents page.



Adventures in Unity – 2.2 Framework



I’m repurposing project 1 for this game – rather than starting from scratch and reusing elements I’m editing the existing code – which is never a good idea; but one I find hard to resist.

I wasn’t completely happy with the game structure with project 1 & wanted to take a stab at reviewing and updating – Hopefully improve things a little. The new version isn’t perfect, but I think it’s an improvement.

It’s based almost entirely on using enums to define ‘states’, managers to switch between states (e.g. GameStateManager & GamePlayManager) & elements which implement different code/functionality depending on the current state.

I’ve outlined each class/element in a bit more details below;



GameStateManager: As with Project 1 (Block Runner) – The game state manager looks after the top level game state – That is, are we on the title screen, highscore screen, playing the game, etc… Top level GSM stuff. It’s still overloaded; but I’ve begun simplified things a little – Game Over is now managed by GamePlayManager (though at the end of a game the GameStareManager still checks to see if the player has a new highscore).

GamePlayManager: Looks after the game state ‘in-game‘ – It’s concerned with things like; initializing the level, displaying the level intro message, playing the game, displaying end of level messages & handling gameover, etc.

Player: Modified from Project 1‘s player class – This is looks after the current state of the player – Are they entering the level, or exiting, playing the game or have they fallen off a tile? It also managers the player input and updates player input accordingly.

A notable aspect is the way player deaths are handled – Once a player is killed, the Player class looks through all the current tiles on screen and identifies all safe/standard tile types (only checking against the top half of the screen) – It then randomly chooses one to be used as the spawn point for the player re-entering the level. If there are no safe tiles currently active, the level will continue to scroll until a safe tile becomes available.

TileManager: Based on the ‘PlatformManager‘ class from Project 1 – Unlike the classes above, this isn’t managed by state/enum.

Each level is made up of tiles – Tiles create the path the player must travel through in order to reach the end of the level. It’s the environment the player exists in while playing the game – The meat of the game.

There are lots of different types of tiles used in the game – e.g. normal/standard tiles act like platforms in a standard platform game – players can safely bounce onto/off-from them as often as they like – Arrow tiles allow the player to bounce twice as far (avoiding obstacles or large gaps in the level), walls block the players path, lava tiles kill the player on collision etc…

The TileManager class manages these tiles – Instantiating, positioning, scrolling and ultimatly destroying tiles.

For the tiles themselves, I’ve followed the example given in the Space Shooter demo code – Each tile type is defined as a prefab; these are plugged into the TileManager class as generic GameObjects – This allows me to easily manage the tile types with the TileManager class, whilst allowing each tile to maintain it’s own personality.

At the start of each level, the TileManager class loads a (text) map of that level. It uses this map to populates a two-dimensional array of GameObjects (Tiles) – This builds the level.

Since levels can be pretty large, so I don’t want to have ALL the tiles instantiated & active at one time – It’ll soak up far too much memory. So the array only holds the tiles which are onscreen at that time (with a little offscreen buffering to smooth things out).

Each loop TileManager updates the position of each tile in the array – scrolling them down the screen – Once a row has moved off the bottom of the screen; TileManager reads the next line from the level map; populates the offscreen row with the new tiles & repositions them at the top of the screen, ready to scroll down and confound the player.

Scoreboard: Currently still fairly undefined – The relevant fields are in place (score, hiscore, lives, jumps) – & I’ve started hooking them up to the game code – But I’m not particularly happy with the way it currently looks in game – So I’m intending to finish connecting to the game data (hiscores are proving a pain) – But then leaving all the heavy lifting (animations, transitions, etc) – Until I decide how I want it to actually work.



There’s a couple of important areas still undefined; the background & enemies.

Background: On the C64 version of the game the background seems to be created out of tiles (as with the top layer) with generic grass, mud, water type images – Using parallax scrolling to give the impression of depth.

Enemies: From what I can gather enemies in the original bounder are made up of two classes/types;

Type 1. Enemies which operate in the expected manner – moving around the screen, needing to be avoided by the player.

Type 2. Enemies which sit on tiles, acting either as one-touch kill obstacles – or in a more esoteric manner e.g. warp enemies, which, upon collision, transport the player to another (safe) part of the screen.

With my current setup, I’m more inclined to class type 2 enemies as tile types.

Though I’m intending to wait until I’ve setup a wider range of tiles before I consider this further.



A short video demonstrating the current framework…




For now that’s it.

For my next step I’m intending to start defining & adding tile types to the game – getting their functionality defined & making them look a little more interesting/unique.

So, first I need to figure out what different tile types there are & how they operate.

Below is a quick video demonstrating how things are at the moment


Play the game (WebGL)


Next post: 2.3 Palette Swap

Last post: 2.1 Introduction

Contents page.



Adventures in Unity – 2.1 Introduction


My second project with unity.

For this, I decided, rather than expanding project 1 (something I’d like to do in the future) – I’d write a completely new game.

I wanted something a little larger – But still keeping the scale ‘reasonable’ – So I can learn & play while I develop.

Eventually setting on a remake of ‘Bounder‘ – a Commodore 64 game released by Gremlin Graphics in 1985.


The cassette inlay explains;

Move Bounder ( tennis ball ) around screen, bouncing on hexagonal
slabs only.  If you miss, you fall to your death. Be sure to
identify mountains and walls as you can't go over them, you must
go around. Any collision means you lose  a life.


(Note – slabs are in fact rectangular with a hexagonal design)

This long play video demonstrates C64 gameplay;

It’s worth noting that Urbanscan a company owned by Ian Stewart (one of Gremlin Graphics founders) – Has released a new version of Bounder on the app store.

Putting this together, I’m intending to try and re-use projects 1’s structure\GSM – maybe tidied & tightened a little – Which will hopefully allow me to focus more on the game itself.

Ideally I’d like to build a more conservative version first – which I can release as a WebGL game. Which I can then expand upon to create a PC version – Allowing me to add 3D models/animations, more involved shaders, etc… Stuff I havn’t really implemented so far… Also allowing me to setup & try out the type & range of configuration options PC gamers expect to see.

Rather than updating every week – This time I’ll try to update every milestone (working on this part time this will more time between blog entries; but hopefully they will be more meaningful when I do publish them).

Lets see how this goes 🙂

Play the game (WebGL)

Next post: 2.2 Framework

Contents page.