Prototyping journal - Making a game in the dark

CHARACTER DEVELOPMENT

Animating the character was a simple enough task. Idle and walking frames were loaded up on a sprite sheet and implemented in Unity’s Animator, along with a simple velocity based character controller.

click any image to get a closer look

LIGHTING

The earliest mockups looked pretty uninspiring on their own. In an effort to capture the feeling of deep, suffocating darkness, I quickly ditched all ambient light and illuminated the scene with a spotlight that follows the player around.

The code below is the light controller for the trailing spotlight. Making the light look at the player was simple, but following proved trickier. It works by calculating the floor distance from the light’s position to the player’s position. It then uses a set “target distance” to tell the light whether or not it should start moving towards it’s target (using lerps to ease the movement). This creates a circle around the player in which the light doesn’t fuss about following them, reducing unwanted light movement. Additionally, it adds a slight bob to the lights movement that happens at all times, which I think helps to smooth the seams during abrupt stops.

POST PROCESSING

Early on I felt the darkness color looked harsh and dead. So I added a post processing volume and edited the color curves. Adding some color to the lowest values helped to set an ominous mood, and now lights cast livelier shadows from large objects.

SHADOWS

2D sprites don’t inherently cast shadows, and that fact started to be a glaring shortcoming as I progressed more and more. So I dove into the URP’s lit shader graph, and was able to piece together the following; which grabs vertex color data and the texture from the sprite and runs them through Unity’s fragment shader to finally produce the elusive character shadow.

The shadow silhouette is formed by standing the sprite up 90 degrees from the floor, tilting the camera 45 degrees, then distorting the sprite so that the correct sprite height is projected onto the camera. This idea was taken almost directly from researching how the developers of Enter the Gungeon handle sprites.

So this shadow method looked great, so long as the light was close to normal to the sprite it was shining on. But as the light approached parallel, the shadow flattened, creating an obvious effect.

I remedied this issue by overlaying a copy of the character sprite at 90 degrees, which isn’t visible to the orthographic camera. This does sometimes create some odd shadows cast onto the main sprite, but adjusting the shadow biases minimized the unwanted effect.

I set up an animator for this perpendicular shadow, same as on the main sprite, and the result is a pretty convincing 3D shadow effect that bounces along with the characters movements. I have to concede that doubling the sprite and animators just to mimic a 3D model is a lot of work, but the resulting style is satisfying nonetheless.

FOLLOW CLICK

As happy as I was with how the look of this environment was coming along, I still felt that the player could use more control when it came to the spotlight. So I got to work adding the ability to control the spotlight via mouse click to my light controller.

I accomplish this effect by having a held click of the mouse cast a ray from the screen to try and collide with the world. When it does, the collision position fills the transform of an empty object, which becomes the new target transform for the light. Additionally, I added some more lerping to smooth the transition from a mouse click target to the player target, and vice versa.

FORWARD LOOKING

As I become more familiar with Unity basics, I’m looking to further integrate my artwork into the scenery and additional characters. This environment is certainly a long way off from telling any kind of coherent story. But as I continue its development, I hope to explore what treasures and mysteries the darkness could have in store.