About orukinawa


Ludum Dare 35
Ludum Dare 33
Ludum Dare 32
Ludum Dare 30

orukinawa's Trophies

orukinawa's Archive

QWER: Making a pixel game in Unity

Posted by
Sunday, May 8th, 2016 8:59 am

Howdy! This is my first post on LD and I thought it would be cool to share what I learned making QWER, my game jam entry for both LD35 and LowRezJam2016.

First of all, feel free to give it a go and rate it if you haven’t yet ūüėČ


Submitting for 2 jams at the same time meant respecting both the theme from LD35 (ShapeShift) and LowRezJam’s rules.

Here’s a summary of the main¬†rules:

  1. Resolution should be 64×64. This means that the game can only have 4096 (64×64) pixels on screen but does not limit your viewport to be 64×64. For example, QWER uses a default viewport size¬†of 640×640 but as each pixel is rendered as 10×10 onscreen, the game resolution is still 64×64.
  2. No inter-pixel movement.¬†This means that objects in the game are not allowed to move in increments lower than 1 pixel. In context of Unity’s transform component, the x,y,z of an object’s position cannot have decimals. (E.g: transform.position.x=10.4 is not allowed)


Taking those rules into account, here’s some¬†tips for making a pixel game in Unity:

  1. Camera Setup
    QWER Camera SettingsFirst at all we have to set the Camera Projection to Orthographic, this is because the game does not require depth and is 2D. The other thing to set is Camera Size. In Unity, an orthographic camera size is defined by the height in pixels from the centre of the viewport to the top. Since our game is 64×64, the camera size (also interpreted as half the height) is 32.
  2. The Grid
    QWER The GridThat one is more of a personal preference thing. I have an empty GameObject called ‘Grid’ under which all other objects in the scene are nested. Notice as well that the Grid’s x and y positions are both -32. What this achieves is that all the nested objects’ ‘localPosition’ values will range from 0-64, 0 being left(x) and bottom(y) and 64 being right(x) and top(y). This makes it easier (for me at least) to deal with¬†object positions compared to (-32 to 32).
  3. Importing Sprites
    QWER Dot Import
    The important settings here are Pixel per Unit and Filter Mode.
    By using a Pixel per Unit value of 1, we make sure that whatever sprite we import will display at exactly the same size as the original. E.g: A 10×10 sprite will display as exactly 10×10 in the game.
    Unity’s default Filter Mode is Bilinear, which smoothes out edges. Since all our sprites are gonna be low rez, the smoothing effect will blur them out. Setting Filter Mode to Point makes sure the¬†sprites willl look sharp.
    QWER Point FilterBilinear:
    QWER Bilinear Filter
  4. Pixel Movement
    Here’s a screenshot of the Pixel Movement Code. Code can also be found¬†here.
    Pixel Movement CodeFirst of all I’d like to say that this is not the most optimized code, but for a small game like QWER, it does the job. This script is basically a base class from which GameObjects that need to move should inherit from. What is does is internally¬†increment the values of x and y positions depending on the speed provided BUT only move the GameObject on screen when the new position reached a new integer.E.g:¬†An object at position x=0 is meant to move 0.4 pixels right¬†each second.
    Second 1: Internal x = 0 + 0.4 = 0.4, Onscreen x = 0
    Second 2: Internal x = 0.4 + 0.4 = 0.8, Onscreen x = 0
    Second 3: Internal x = 0.8 + 0.4 = 1.2, Onscreen x = 1That way, we make sure that we abide to rule #2 which is No inter-pixel movement while still allowing for all kinds of¬†move speed values.A Vector4 is passed in as parameter where x,y,z make up the position of the target and w is for the speed. Here’s an example of how it is called from a derived class: QWER Derived Code Annotation


That’s about it. Hope some of you guys got something useful out of this. If you wanna know more, the source code for QWER is available here. If you have any questions,comments or suggestions, you can reply on this¬†post or contact me on Twitter¬†@Orukinawa

[cache: storing page]