Art Design Deep Dive: Dynamic 2D lighting in Dwerve

Sept. 14, 2020
protect

Who: Percy Legendre, developer at Half Human Games

My name is Percy Legendre and 2 years ago, Peter Milko and I founded Half Human Games, the small indie studio working on Dwerve, a Zelda-like action RPG with tower defense combat. As indies, we juggle multiple responsibilities. I do programming, game design, writing, and even art at times.

With a small team of just 2 full-time developers, we had to come up with creative ways to make our game look and feel unique without investing too much time.

What: Dynamic lights and shadows for 2D games

We knew from the very beginning that we wanted to push the boundaries of SNES-style pixel graphics with Dwerve. We wanted the player to dungeon crawl through dimly lit dungeons to further immerse them in our fantasy world.

When it came to lighting, a combination of technical and creative skills helped us add beautiful 2D lighting to Dwerve using a Unity Asset called Smart Lighting 2D. Hopefully you can still take away insight from this article even if you use other game engines or lighting systems.

Create a new Unity project using the 2D template and import Smart Lighting 2D into the project. Make a new scene and add a Unity Tilemap by right clicking the Hierarchy window and selecting 2D Object/Tilemap. Make or find a dungeon tileset. Itch.io has a ton of free top-down tilesets. For this article, I am using Pita's Dungeon Tileset which we used as a base for Dwerve assets early on in development. I will recreate the scene below with lighting:

In the sprite import settings, set the Sprite Mode to Multiple, the Pixels Per Unit to 16, and the Filter Mode to Point (no filter). Then open the Sprite Editor and slice the grid into 16 x 16 cells.

You will notice that many sprites are larger than 16 x 16 pixels and are cut into 2 or 4 separate sprite slices. Fix each one by deleting the extra sprite slices and resizing the other to encompass the sprite entirely. Make sure to keep the length and width a multiple of 16. In the image below, the red outline shows the generated sprites, and the blue outline shows what you need to make it look like.

Next set Pivot to CustomPivot Unit Mode to Pixels, and Custom Pivot to (8, 8). This makes sure the sprite will align properly to the tilemap grid.

Don't forget to adjust the positions and pivots of the torch sprites and any other large sprites. When you are done, click the Apply button to save the changes.

Next we need to generate tiles from the Tile Palette window. Open the window from the top toolbar by selecting Window/2D/Tile Palette. Then create a new tile palette called Dungeon Palette and save the tile palette to a new folder Assets/Palettes.

To automatically generate tiles from sprites, just drag the sprites from Assets onto the Tile Palette window. When the Select Folder dialog pops up, create a new folder Assets/Tiles and generate the tiles into that folder.

Your Tile Palette window should now look like this:

Before we start painting our tilemap, let's duplicate the Tilemap game object in the Hierarchy window. Rename the first tilemap game object to Ground Tilemap and rename the second one to Obstacle Tilemap. For the Obstacle Tilemap, set the Order in Layer property of the Tilemap Renderer component to 10 so it renders over the Ground Tilemap.

Now paint your tilemap. Make sure to paint the ground tiles on the Ground Tilemap and the walls, pillars, and props on the Obstacles Tilemap. Skip the torches for now, we will add these later. I am going to paint the tilemap shown at the beginning of this article, but feel free to paint your own.

In the image above, take a look at the furniture by the wall in the bottom right. Notice how the wall is rendering over the furniture. We can fix this in the Project Settings. Open the Project Settings window from the top toolbar by selecting Edit/Project Settings.... Then select Graphics. Under the Camera Settings section, set Transparency Sort Mode to Custom Axis and Transparent Sort Axis to (0, 1, 0). Now the furniture tiles should renderer over the wall tiles.

Next we want to add a collider to our tilemap. Add a Tilemap Collider 2D component to the Obstacle Tilemap game object, and tick the Used by Composite checkbox. Then add a Composite Collider 2D component. This will also automatically add a Rigidbody 2D component. Change the rigidbody Body Type to Static. Select the Obstacle Tilemap game object. Your collider should look similar to the image below.

You might notice a problem with this collider. We want the collider to only be at the base of the objects, not entirely encompass the sprites. Open the Sprite Editor window from the texture import settings and edit the custom physics shapes for the sprites by selecting Sprite Editor/Custom Physics Shape in the top right. Edit the custom physics shapes to include the base of the objects as shown in the image below.

Select Obstacle Tilemap in the hierarchy. If the colliders do not update automatically, disable and re-enable the Tilemap Collider 2D component and the colliders will update. Your colliders should now look like this.

Next let's add the torch tiles. Select the Grid game object and create a new tilemap by right clicking and selecting 2D Object/Tilemap. Rename the tilemap Torch Tilemap and set the Order in Layer property of the Tilemap Renderer component to 20.

We want the torch tiles to be animated. Thankfully, Unity 2D Extras includes AnimatedTile.cs. Since we just need that script, you can download only that script and put it in 

JikGuard.com, a high-tech security service provider focusing on game protection and anti-cheat, is committed to helping game companies solve the problem of cheats and hacks, and providing deeply integrated encryption protection solutions for games.

Read More>>