We'd like to give you some insights into how we get a finished drawing of a scene into our game Unforeseen Incidents and how we make it actually playable.
Implementing a finished Photoshop scene is one of the less creative and more annoying tasks we face while working on the game (so why not share that experience with you, right?). Once we finish the scenes we can't simply drag & drop them into the Unity engine (I wish we could). Firstly, the scenes consist of lots of layers. Secondly, the images are huge. We create the graphics for the game in 4k resolution. To support all graphic cards on possible target devices, we have to cut the images into smaller images. We're working with a 2048x2048 px restriction.
This means: in each scene image, we have to slice the layers wider or higher than 2048px into smaller pieces, then export all layers separately, then bring them into a format that our game engine can work with and import and implement them there. A format like this would be a sprite sheet - collections of parts and layers in new graphics not bigger than 2048x2048 (I feel like I'm repeating myself. But then, maybe that's just the spirit of background slicing. Doing things over and over again. Making mistakes. Doing everything again and again and again).
Luckily, we have some tools that help us with all these (annoying) steps. Imagine we want to implement the following scene:
This graphic is has a size of 3840 x 2880 px. What?! 4:3?! Yes, which part of the image gets displayed is depending on what kind of device/display one uses to play the scene. Usually, the game will have a 16:9 or 16:10 (again, depends on what you use) resolution. Parts of the image will be cut then.
This picture consist of a number of different layers, because you need to be able to interact with the scene in the game - the door can be opened, the phone can be picked up, the fire is animated. The characters should be able to walk behind the desks. The layering of the scene in Photoshop looks like this:
You can guess that some of the layers might be too big for our 2048 px restriction. At least for the layer 'Background' you can tell without checking - it must be too big. Now we need to slice those layers into smaller ones. We wrote a little Photoshop script that helps us out. It finds all layers that are wider or higher than 2048 px and cuts them into smaller pieces. This little script saves us hours of work. It not only slices the layers, but it also makes sure they have a slight overlap. There's some kind of floating point precision error inside the Unity engine that causes non-overlapping, clung 2D layers to flicker when the camera moves. Since we don't want flickerings in the game, we let the slices overlap with a few pixels. After the script ran, the layering looks like this:
In this case, 'Background' was the only layer that needed slicing. This is different in other scenes that have bigger objects or more layers than this one. The background in our scene now consists of four parts. To illustrate the result, here's a spaced out version of the new four background layers:
What's next? To create a sprite sheet, we firstly export all layers into separate PNG files. The newest version of Photoshop has a function to export layers, but it automatically trims the layers. We don't want that, because we want to keep the positions of the objects in the room. So what we use is a script that was included in old versions of Photoshop. It's called "Layers to files" and does exactly what you'd assume:
It saves all layers into separate PNG files (and keeps the positions). In the next step, we use a little software called TexturePacker to create the sheets from these files. After feeding it with some information about how we want them, it helps us creating the sprite sheets. For this scene, the outcome looks like this:
These are now seven new PNG files which work perfectly in our engine. Since TexturePacker works really well with Unity, all we need to do is click one button to export those sheets into our project. After adjusting the import settings in Unity, we're done importing the sprites. As you can see, TexturePacker now trims the sprites - but it remembers their original position by setting up a pivot point that refers to the previous center of the scene. All objects will be positioned in (0,0,0) in Unity and then appear in their original position. Pivot points in (0,0,0)??! Stay calm, stay calm. If we want to rotate an object properly, we can parent it into a new Game Object that functions as a rotation pivot point.
All these steps need to be processed for each of the ~60 scenes of the game. Fortunately, a lot of work is automatized, which makes the whole thing less error-prone. The photoshop actions and scripts can be executed with just one click for all scenes of the game (batch processing). Then we need to do some manual clicking and waiting in TexturePacker, but it could be much worse, right?
Next task after importing the sprites is getting the backgrounds in objects in an actual scene in Unity. This is something we will cover the next time. Until then, let's be happy we successfully managed to import that beautiful scene into the engine.
This post has been reposted from http://www.backwoods-entertainment.com/blog