From Photoshop to Unity

Hello world! My name is Ben, and I’m a code addict.
This is my first time here, so on behalf of the Swing Swing Submarine team I’d like to welcome myself to this blog, yay!

With Tetrobot and Co done and Seasons after Fall starting, I want to use this transition time to share some of the tools and techniques that we’ve developed during Tetrobot and Co. Today: some Photoshop magic!

The menus of Tetrobot and Co were fairly (ridiculously?) complex, with multiple layers, many animated elements, doors opening and closing, and seamless screen transitions, so we knew a traditional, square-buttons-on-a-static-background UI system wouldn’t cut it. We had to make it easy for Géraud, our illustrator, to design as much as possible in Photoshop, and bring it effortlessly to Unity, animation-ready.
The basic idea: he draws as usual in Photoshop, using as many layers/groups/etc as he needs, and when importing the PSD files in Unity we extract each layer into a PNG, as well as the extra data (layer size, position, and depth, mostly). We also replicate the group structure, so with one click of a button we end up with a Unity hierarchy that is an exact match for the Photoshop layout.
Then when he changes the PSD, he only has to regenerate the textures, and can optionally also synchronize the scene.

main menu in Photoshop

The main menu in Photoshop

main menu in Unity

The main menu in Unity

For the tech-inclined: we use PsdPlugin, an open-source, .NET native PSD library to read the PSDs, an EditorWindow to setup the layouts, and store the data in a ScriptableObject (called PsdLayout).

main menu import window

The PSD import window.
Right panel was supposed to be a preview of the layer but I could never get it to work 😉 !

main menu PsdLayout

Layer data extracted to a PsdLayout

Note that we started development well before Unity 4.3 and its sprite system was out, so in retrospect some aspects feel clunky, but really the concept is quite similar. In particular, putting all the layout data in a single ScriptableObject was a mistake: Unity’s approach of making each Sprite an object is way better, you get true references that you can drag’n’drop and whatnot. At first I didn’t think of it, and by the time I realized the shortcomings I was too pressed for time to change it.
I actually think that with a little polish, one could get pretty close to their system, all from user code. Maybe for projects that can’t be upgraded to 4.3? I know many users are still stuck with Unity 3.5!

In the end I counted over 600 individual textures. And before you ask, no we didn’t ship with any kind of atlasing; it’s a draw call fiesta, but it fits even on low-end PCs so whatever. Not sure this will fly on mobile devices though, but since the system is fairly automated, repacking and converting everything should not be an issue if we need to.

main menu layers to PNG

All the layers are automatically extracted to individual PNG files.

The lion share of it is one giant PSD for the 4 screens of the main menu (3756×1536 pixels, 44MB). Then we have a separate one for the robots, one for the level end screen and all the ingame buttons, and one for each cutscene. We even did the ingame backgrounds this way.

tetrobots in Photoshop

The chapter bots in Photoshop: each bot has its own group, all in one PSD.

tetrobots in Unity

The same bots in Unity: the system proved great for animating character rigs!

Basically it was up to Géraud to decide how he preferred to work: I suspect that as long as his computer doesn’t choke on RAM usage, he’ll just throw a billion layers on a single PSD: more power to him 😉 !

The only downside is version control: as the PSDs get bigger, synching becomes a bit painful. The main PSD peeked at 44MB, so still nothing insane compared to some 3D workflows, but each time you edit even one layer you’re up for a big upload. I’m pretty sure we could do better though, unfortunately I’m no source control expert, I could never understand if Mercurial supports deltas on binary files… maybe the bigfiles extension would help? maybe we should switch to PlasticSCM?

Although I do hope Seasons’ menus will be a lot less complex than Tetrobot’s, I’m sure we will reuse this system: having the ability to read the actual layers from a PSD file is so powerful that it can be used in many other contexts than menus. If you look at the 3D world, a lot is invested into the tools so that content creators can push data to the game engine. In comparison, much of what I’ve seen in 2D is pretty meek, and I believe we can do much more.
At the very least I’ll update the tool for Unity 4.3 to export to spritesheets, but I have many more ideas: applying masks Unity-side (instead of flattening them Photoshop-side), taking advantage of Smart Objects, or even custom metadata (just like 3DS Max or Maya attributes), perhaps to setup pivot points or collision outlines or whatnot, using per-layer timestamps to only update changed layers, which would then cut down on import time so that we can automate it (basically use an AssetPostprocessor instead of our EditorWindow)… etc etc.

Also see: A good workflow to smoothly import 2D content into Unity, Part I and Part II. Their approach is to process the data Photoshop-side instead of Unity-side. Although I suppose some things would be easier to do from inside Photoshop (like applying masks etc), other things are easier from Unity, like writing custom data, creating materials, etc.
In the end, I simply felt more comfortable investing in C# code rather than learning Photoshop scripting (though it seems pretty straightforward), and more in control of the workflow (no need to setup the scripts in each workstation etc).

Well, that’s it for today! Any topics you’d like to see discussed here?