Unity2D

With the rise of the mobile market, 2D games have become more popular than ever. Titles ranging from the casual side of Candy Crush to the esport of Hearthstone. There’s no denying that 2D games are still popular. As such Unity developers have adapted their engine to smooth the process of making 2D games in their engine. What follows is an analysis of Unity2D’s RectTransform.

Engines, how do they work?

When making 3D games, the gamespace is a three dimensional space (obvious, right?) but not quite. It’s actually lots of three dimensional spaces – each object in the game space has it’s own coordinate system of which it is at the center, this objects children have coordinates in their parents coordinate system. This lets you move an object (a car say) in a direction and all of it’s children (doors, wheels etc. ) stay in the same place with respect to the parent.

This already poses a serious problem to those making games. It needs to be displayed on a 2D screen. They way we solve this is to pick a viewpoint – this is the eye or the camera of the game. It takes everything it sees and applies a matrix transformation to bring all of the objects into the root coordinate system or gamespace, now it can generate perspective on it’s 2D rendering of the gamespace.

When it comes to 2D games this process is much simpler, the root gamespace is simply the screen area, there’s no need for a camera and there’s no need for any fancy perspective. Things are the size they are and that’s that. We still have child and parent coordinate systems as it’s still useful for moving groups of objects – but because we don’t have perspective we can use the width and height of objects in the pixel dimensions on the screen. In addition it makes sense for parent object to take the bounds of their children as all of the display objects have a position, width and height and will be displayed of a quad (rectangle) of the same size. The position, width and height of this quad is useful and easily calculable.

In Unity2D the engine still assumes perspective, as Unity2D is a cross-section of their 3D  engine. There are many tools that the Unity team has developed to ease the process of making 2D games, however there are some pitfalls that I’ve found.

Scrolling Example

Say you wanted to make a list in your game, It might be a leaderboard or a settings menu. In this example we’ll use a settings menu. In an explicit 2D engine this would be as simple of adding each setting in turn to the parent scrolling panel and setting the y coordinate of that setting to be equal to the current height of the scrolling panel. This ensures that each child has enough space to be completely visible without overlapping whatever the size of the child. This is because the parent’s height takes into account it’s children’s height.

In Unity2D the parent’s height does not reflect the height of it’s children. Therefore this method becomes far more difficult, especially when, in our settings menu, each child (option) may contain a name, a slider, a checkbox. Unity’s solution to this is to use a combination of the VerticalLayoutGroup, ContentSizeFitter and LayoutElement. While this works well for lists of objects about which the size is known, it breaks down if things start to change size. Essentially what this solution requires is a knowledge of the dimensions of all the settings menu options beforehand.

In my game I made sure my options had plenty of space, such that each option would be the same size. But I’ve yet to find a solution that I like as much as the explicit 2D solution. If you’ve found one, let me know.

Palette Swap Shader

A palette swap is a technique used in games. It is the computational equivalent of colour by numbers. In colour by numbers you get a page with some numbers identifying a series of shapes, and a collection of little paint pots with numbers on the lids. The numbers tell you what shape should be which colour. The computer does the same thing with the palette swap. The computer wants to render a picture, each pixel of this picture has a colour code. (An RGB number is 3 numbers that identify a number in terms of how much of Red, Green and Blue to mix) The computer takes the colour code to the palette and the palette exchanges that number for a new number and, in doing so, swaps the colour that would have been rendered. This technique was initially developed to be able to show a lot of different types of characters using only one texture. This allowed developers to save a lot of space in the memory and has been used ever since.

The reason I’ve been developing a palette swapping shader is for use in my gravity inversion game. I found it quite difficult to sense which direction gravity was pointing, kind of the whole point, so I decided to completely change the colours of everything on the screen while gravity was inverted. This let me quickly change the colour of all of the textures rendered in my game by only changing a small 16 pixel sprite. I found that using this didn’t cause any noticeable slow down, even on mobile devices. Then I came to the idea that, if the palettes are small and easy to produce, why not let the player choose which colour schemes they would like.

I’m developing my game in Unity2D, so how did I manage it? I give two textures to the shader. One is the original texture, the other is the palette. I then need to convert the colour of the first texture into the coordinates of the second. I decided to use the number for the red composition only and then use that value of between 0 and 1 to translate to how far along the palette to go. Once I had the new colour I was nearly in the clear. I also wanted to preserve the transparency of the original texture, so after changing the render type from opaque I copy the old alpha (transparency) value to the new colour. I’m using textures not sprites to preserve texture scrolling for my parallax background.

After putting it all together, I’ve found it works well. All I have to do is send an event to the ColourInverter script I wrote which accesses the shader properties and swaps out the current palette. I decided to do it this way as I found the shader if statement to be less efficient than changing the palette texture (I haven’t tested this on low end phones.)