Game A Week 3: Ballface in the Dark

OK, sorry that I had to cheat with this one but my weekend was completely booked and the game was unplayable (about 50% finished) by then.  While I have read that the “gist” of this challenge is to release something every sunday no matter if it’s ready or not, I really wanted to have something at least a little playable to release. And I am going to release another one this week’s sunday anyway, so it’ll work out, right?

The Game

Ballface in the Dark is a mysterious sidescroller with a special twist! Cool name, huh? It took me literally two seconds. The player can use a flashlight to light their way in the darkness and find the hidden treasure that is buried within! And this time the protagonist is not a cube! Hooray! I made this game 100% 2D by drawing all of the sprites and the player animations by myself. You will probably notice that right away.

Development

New things I learned this week were:

  • the animations for the player
  • using a spotlight as a flashlight
  • how sprites behave with lightsources, and 2D lighting in general
  • turning the player and the flashlight based on direction
  • collectible tokens (read: coins)

The animations were quite straightforward. I used a few YouTube tutorials to get the hang of it and then it was just drawing the individual frames and upping them to Unity. Like last time, I used Gimp to draw basically everything. The movement animation does look a little weird sometimes when the player stops: there’s an extra “skip” in the end which could have been smoothened out somehow.

The flashlight is just a separate GameObject with a Spotlight component bound to the player’s GameObject. The way lights work with sprites wasn’t straightforward however. The default material sprites are made of, aptly named Sprites-default, do not react to lighting at all. When using this material, the sprite is always the same level of brightness. Instead, the material had to be changed to Sprites-diffuse. This material works with lighting the same way 3D objects do on default. After I had figured this out, there was another problem. The lighting looked very weird between tiles of the background. Below is an example of this situation.

Shader problem with 2D lighting.
Shader problem with 2D lighting.

As you can see in the image, the lights did some weird stuff on the shaders so you could clearly see the borders of the background tiles. However, although it took me a long time to find it, the solution for this was pretty simple. The Render Mode on each lightsource had to be changed from Auto, which it is by default, to Important. I don’t know what it actually does, but it worked as you can see in the final product.

Another problem I was having for a while was turning the player when the direction of movement was changed. At first I tried it with the property transform.eulerAngles.x, and while it worked, there were issues. With this property I essentially turned the whole GameObject around 180 degrees so it would face the other way (think: flipping a sheet of paper). However, in Unity there is this feature called culling, which means that only the things facing the camera are rendered to save processing power. In 2D this means only the front face of the sprite has the attributes that make it unique, such as the material. The problem was that when the player turned left, the “culled” face of the sprite was turned towards the camera and it didn’t react to light at all. My first instinct was to somehow remove culling from the back of it, but I thought this solution would have been way too convoluted and there had to be an easier way.

Luckily there was! Instead of turning the whole GameObject, I could just mirror the front face each time I moved left. This was done by multiplying the player’s transform.localScale.x property by -1, i.e. flipping the direction of the GameObject’s x-axis. And it worked just fine. There was still a problem though. The player’s flashlight still only pointed right. For this I used a hardcoded fix by modifying the rotationVector.y property of the spotlight to point either 77.5f when moving right or 282f when moving left. A lot of googling was done to find out the fixes for all of these problems, but thank god for Stack Exchange. The problems you face usually have already been solved by someone else.

Making the tokens (coins) were very easy compared to everything else. Create empty GameObject, apply Sprite Renderer, apply sprite to Sprite Renderer, tick box to make it a trigger, code it to work with player, bind a Destroy() method and play an audio file when the player touches it.

Phew… well that’s that. It’s 1:34AM and dark outside… Now to play some Alien: Isolation! Oohohoo! I can’t wait!

Leave a comment