top of page

Unity 2.5D Fantast Test

Download Link (Itch.io):  https://miffins.itch.io/2d-fantasy-test?password=fake2d

GitHub Repository: https://github.com/BaffleBird/2D-Fantasy-Test

​

Overview

This is a visual test prototype done in Unity. In one of my previous projects (Forge of Spirits), I partially explored the creation of a 2D game within 3D space, though the focus was combat mechanics. This time, I wanted to focus in on the creation of 3D effects and lighting in an otherwise 2D game. This project is largely based on various progress posts on the development of Eastward by Pixpil.

​

The Built-in Render Pipeline

This prototype was made in Unity's default render pipeline rather than the more recent Universal Render Pipeline (URP). There was a particular shader (by traggett on github) that I relied on for rendering the sprites within a 3D space, which doesn't have a version for URP. I also wanted to better fundamentally understand shaders through Unity's Shaderlab code as opposed to Shadergraph. That said, this project can probably be accomplished in URP as well, so long as you understand a little bit about shaders and rendering.

Angles and Assets

The biggest trick to this whole set up is the angle and scale of everything in the scene. Eastward is set up such that the camera is strictly aligned to the z-axis and all 'standing' sprites are positioned as normal, facing the screen (essentially billboarding). The ground and other 'horizontal' planes are slanted away from the camera by 45 degrees and vertically stretched by about 1.414. As an object move along the xy axes, the object's z position is adjusted to match the y position, so objects are essentially moving in 3D along the slanted ground.

Tilemap Shenanigans

Unity's Tilemap package usually isn't used in 3D the way I used it here, but it's possible and it made level construction much easier than other 3D shenanigans. Tilemaps also have functions to help make it work. 

  • You can have multiple Grid objects and multiple Tilemap objects under a Grid object. In my case, each Grid made up a 'floor'. Each 'floor' would have at least two Tilemaps - one for floor tiles, one for wall tiles.

  • You can set a Custom orientation for a Tilemap object's tiles. You could rotate and scale tiles to a standing position facing the camera. This is how I made the walls in each Grid level.

Foliage and Fish

A large number of plants in this test were made with quads mapped to a sprite sheet and attached with Spring logic monobehaviours to be interactable with the player. These would be more optimized with a shader (and a little less interactable), but I was wary of tinkering too much with traggett's shader. Instead, Foliage is activated and deactivated based on distance to the Camera for performance. The fish are boids that were made by following Board To Bits' Flocking Algorithm series on youtube.

3D Meshes

To better leverage 3D lighting effects, objects would visually benefit from more tailored geometry. For example, the stairs in this scene were all modelled in Blender and UV mapped to a sprite sheet. This lets lights and shadows cascade over the steps more realistically than a flat sprite with a normal map.

Shaders

At the core of everything I wanted to accomplish with this project is the shaders, which determine how meshes and pixels render on the screen. There were two main objectives I wanted to achieve:

Rendering Sprites like 3D Quads

Unity's default sprite shaders rely on positional depth sorting. This causes rendering issues and sprites to disappear when you move your camera along the z-axis. The sprite shaders don't always react to light the way you expect them to and washout the sprite's colors (which also happens with Unity's Standard Transparent/Cutout shaders).

I came across traggett's Unity Sprite Shaders, which magically did everything I needed it to (and more). Sprites would write to depth, properly react to light and shadow, and still maintain the color saturation of the original sprite as made in Aseprite. It doesn't have a version for URP, but you could probably recreate the essentials in Shadergraph.

Water Planes

This is a big reason why I wanted to do a 2.5D set up. Eastward has water planes that have a physical height to them. This meaning you could literally pull the water up to a sprite's ankles, flood hallways, etc. and everything beneath the plane will appear underwater. That said, you can apparently write water shaders a million different ways. I went with hacking together bits and pieces of Catlike Coding's Flow tutorial series until I got a shader that did what I want. Mainly making things blue, distorting them with shifting normal maps, and waving the the vertices of the plane.

Lighting and Shadows

Another big reason for the 2.5D set up was that it made depth lighting much easier to do. Not too much special going on here, though I'd like to touch on a couple points.​

​​

​​

Directional Light Cookie - The sun spots in this scene are actually all one giant directional light cookie. I felt directional light cookies worked best since spotlights have spot angles that tended to blend and bleed oddly with this setup. The catch is that Unity seems to run less efficiently with multiple Directional cookie lights, so I drew up one big texture and made that the one directional light cookie in the scene.

​

Blob Shadow - Typically, people just have a texture sliding along the floor beneath the player's feet. Eastward has a mix of both static shadow sprites & blob shadows that cascade like light. Unity's only built-in resource for amorphic blob shadows (at the moment) is the Projector. The Projector only takes into account the mesh it hits and not any transparent textures, since it works by applying a shader to meshes it collides with. There are probably other techniques for getting blob shadows, but it serves well enough for this project.

Credits

​

Tools and Resources

​

bottom of page