Unity2d entities in a 3d world, why you shouldn’t do this

Sometimes I have really stupid ideas and a bit of time to waste. The base architecture for my st’hack challenge is an example of that, how I can really push a bad idea pretty far.

As you probably know (I like this formula, I use it a lot), a few months ago, Unity released its native 2d layer, with tons of new components, and a fully integrated workflow with existing 3d tools. That actually caught my interest : can you do a 3d game with the new 2d entities? The st’hack project was the perfect sandbox for this test, as I was into random dungeon generation. So, with my tileset and some Sprite game objects, can I generate a full 3d dungeon. The point is that the Sprite workflow is really simple, and it’s basically a drag and drop to create a 3d transformable entity. If you’ve checked out my executable, you’ll realize that there are no height levels, the whole dungeon is flat. It is still rendered in 3d with Sprite game objects, and as you might have seen, it’s awfully buggy.

Let’s breakdown the problems:

  • sometimes, the dungeon won’t generate. This is actually fairly easy to understand and the base limit to my idea : Unity2d entities, even though 3d objects, limit themselves to 2 axis, X and Y. What happens, at random, is that at object generation, something resets the Z axis which I use for depth placement. This means that every gameobject gets positioned on the 0 value of the Z axis, and since the player starts around [-16,0,-16], well… you can’t see any dungeon (duh)
  • the Sprite class draws on call order, and since the Z axis is not taken in account, there is no notion of depth testing. Meaning that if a Sprite gameobject behind another is drawn after the latter, it gets drawn in front of it. Overlapsing and shit, and this call order is pretty random on the same draw layer. You can in fact organize them with the draw layer feature, but this is totally wrong when it comes to 3d projection, as this needs to be totally dynamic when you modify the view model.
  • shaders. I can write a lot on this, but it actually is a noticeable problem with base 2d workflow in Unity. There is no dynamic lighting notion for Sprite objects by default. No matter what type of light or render type you choose, it won’t do anything on a Sprite object. This can of course be bypassed by changing the draw shader to a manually created diffuse sprite shader (create a new material and select this shader, affect it as material to Sprite Renderer). This should be enough if you remain into a 2d projection, but when it comes to 3d, you get the previous problems plus a shitload of math what the fucks from the Sprite class.

So yeah, it’s pretty impractical. And definitely a bad idea. Don’t do this at home kids.

So, what’s next? I plan on redoing this demo properly, aka the hard way : create true 3d objects with textures instead of sprites, reuse my algorithm, release this open source. And everyone will be happy, and the world will keep turning.

Have fun, code safe.