Play Expo Glasgow was a great success!

Hi everyone!

We went to Glasgow from the 11th to the 12th of June at the Play Expo Glasgow to present an enhanced version of our latest game, Dragon Bros. We were pleased to meet a lot of players and so many interesting people from all over the country.

Here's Braehead Arena

Here’s Braehead Arena

We got a lot of favorable feedback that reassures us about the evolution of our game. We were also given a few cool ideas to add to the game.

Some absorbed players

Some absorbed players.

We also organized a “Winning T-shirt” contest witch consisted in¬† establishing the fastest run of our demo. Finally, we are glad to announce that we have two winners (2:38 !!) who will soon receive their Dragon Bros T-Shirt.

Our T-shirt really rocks, isn't it!

Our T-shirt really rocks, isn’t it!

As usual, we were not able to resist the possibility to try the others good looking games on the show floor. One game in particular caught our attention. It was Observatorium; that’s clear those guys worked hard on it! Furthermore, we met some really cool other developers: Sociable soccer, Dare the monkey…

An unexpected guest between Guilhem and Lorenzo.

An unexpected guest between Guilhem and Lorenzo.

According to us, it was a great moment spent in Glasgow. We also would like to take this opportunity to thank Andre and Craig from We throw switches!

Social media frenzy

Southampton game fest was ace!

Hi everyone!

We went to Southampton last Sunday to show our latest game, Dragon Bros, at the Southampton Game Fest. It was a loooong day, but it was totally worth it! We received an incredible amount of positive feedback concerning the game, and a lot of brilliant ideas to implement. We met a lot of cool persons, developers, gamers, journalists, students and parents that got dragged in by their kids and enjoyed it much more than they thought they would!

Gamers at Southampton

Gamers trying Dragon Bros

Overall, the game difficulty seems good and people came back more than once to play it! Kids loved it, old gamers loved it and even moms loved it!!! Actually they told us that it was less violent than the usual games their children play!

Stand at Southampton

Cookies, goodies and a cool game, the perfect gamer trap?

We had a contest running for the fastest play through of the demo and people really tried hard to make it. We sorted out the winner today and we are happy to say that Robert F. will receive his Dragon Bros T-Shirt soon! A big thanks to him and everyone who participated in the contest!

We also tried some other games as well and some were really ace. I think 88 Heroes was especially good, so we’ll keep an eye on it!

88 heroes stand at Southampton

88 heroes stand

Last but not least, we want to truly thank Patrick and all the team who organized this event. It was really ace and as an exhibitor we were treated like kings. Or queens. Or space lords. Well, you get what I mean! So a big thumbs up to everyone!

Lorenzo at Southampton

A very unhappy Lorenzo

Gabriele at SouthamptonA truly sad Gabriele

 

Social media frenzy

New Demo available!

Dragon bros has a new demo available ! Check it out here, and don’t hesitate to leave comments!

We included one level only and put a short tutorial up front, but it is supposed to be one of the last levels you play. So it might be a bit on the hard side!

Oh and please follow the Readme.txt instructions if you have trouble launching it on Mac.

Have fun!

Social media frenzy

We are exhibiting at the Southampton Game Fest!

We are excited to announce our participation to the Southampton Game Fest as an exhibitor! Want to try Dragon Bros out? Chat with us? Share cookies while playing a Street Fighter 2 game? Head out to Southampton!

We will bring a couple of laptops and a lot of pads for everyone to try out the game, and will host a couple of Dragon Bros contests. And if you win, we have a special prize for you (such as a t-shirt or steam key, that’s how crazy generous we are! ūüėõ )

We will also discuss our next projects (Vampire, Guns and Rock n’ Roll) and a brand new super awesome project called The Late Resistant!

So book your £6 tickets and come to see us!

Southampton Game Fest 2016

 

Social media frenzy

Dragon Bros will be the first 2D game to support VR!

Edit: this was an April Fool post of course, thanks you all for not disclosing it too early!

Alright, we wanted to announce it for sooooo long, but today we can officially shout about it: Dragon Bros will support VR! We have finally nailed the correct way to do it and ported the game to the Oculus Rift last week.

For those of you who haven’t heard about Oculus Rift, it’s a virtual reality headset that got bought by Facebook some time ago. And it’s awesome!

oculus

Sony, Microsoft and smaller players have also announced their own VR headsets and we hope to support as many as possible.

In the meantime, Marco is still drawing incredible enemies. And we can’t resist to show you the progress on the last one, a giant mech we love to call the “Metallic Michael Jackson” (an awesome bug used to make it walk backward, as if moon-walking!) :

2times res

Challenges we faced

The biggest difficulty was to find a way to keep the 2D feeling in a 3D world, where the player can turn his head and see the side of our sprites. So we reticulated the orthogonal billboard that we use as our classic screen projection plane, and babaaaam that was it!

oculusDragonBrosA quick glance at what it looks like eventually

We were really worried about loosing our pixel perfect display as well, but it actually looks really good. In fact, it feels even more like those old games we played on cathode tube TV as kids: the distorting lenses slightly blur the pixels edges and saved us the need for a specific camera effect shader (at least in VR, we’ll still have to do it on classic screen!)

Still supporting local multiplayer!

Because Dragon Bros is a fun local multiplayer game first and foremost, we had to come with a way to allow two players to play at the same time. We thought about connecting 2 Oculus Rift to the computer, but it has two main issues:

  • it’s super pricey
  • the computing power used by 1 device is already high: 2 screens at 60 fps each, that’s 120 fps for the whole thing already! So going 2 device would be 240 fps, it’s far too high even for last gen consoles.

So we came up with a crazy idea: what if players could share the headset? After all it’s got two screens (one per eye). So we tried it, and it works! It feels a bit cozy, which will be awkward for sure when you play with your mom. Though it could be a cool trick to get closer to your secret love!

IMG_20160401_110318700Lorenzo and Guilhem trying an early version of Dragon Bros on google cardboard

The biggest challenge we face now is that on Occulus, every player has his own camera, while on flat screen they share a unique camera. The consequence in term of gameplay are quite high, but I am sure we can make it!

Social media frenzy

Using singletons in Unity

Hi everyone! I hope you are ready to get some great Easter holiday time? Or maybe advance your Unity projects? If so, this may interest you!

I am Guilhem, the main programmer at Space Lizard Studio and I will discuss the use of singletons in unity, how to mix them with monobehaviors and get a clean implementation of those.

This course is for beginner or intermediate programmers, or advanced programmers starting to use Unity.

What is a Singleton?

A singleton is a design pattern for objects that are not supposed to be created more than once. A music manager for instance: you probably don’t want more than one music manager in your game at any given time. The Singleton helps you to enforce this rule, and gives you a shortcut to access this music manager.

A very simple singleton implementation could be:

public class Singleton <T> where T: Singleton<T>, new()
{
    protected Singleton() { }
    public static T Instance 
    { 
        get 
        {
            if (instance == null)
                instance = new T();
            return instance; 
        } 
    }

    protected static T instance = null;

}

[...]

public class MusicManager: Singleton<MusicManager>
{}

Let’s start with the first line: “protected Singleton () {}”. Here we say “hey that constructor is off limit, you can’t create a singleton by using new Singleton<T>() or new MusicManager()”. Instead, we want people to use the property “Instance”. So to access the music manager, you would do MusicManager.Instance(). If it is the first time someone call the music manager, then it will create a music manager. It will save it in a static variable called instance (with a small ‘i’). The second time someone calls the music manager, it will find this already created instance and return it. No one can create it twice anymore!

Why should I use it?

Because it’s crazy convenient. First, you don’t need to check if a music manager already exists, or not, or how to handle two music managers, etc. But the second and most important reason, is that now you can call MusicManager.Instance from anywhere in your code. Let’s say you have a MusicChangerEvent for instance, you can easily do something like that:

MusicManager.Instance.SetMood(MusicMood.Mysterious);

What if I want a MonoBehavior singleton?

As you get used to those convenient Singleton, you may wonder how to make them monobehaviors AND singletons? Well it’s a bit different, but not necessary more complex:

public class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
    public static T Instance { get { return instance; } }
    protected static T instance = null;

    protected virtual void Awake()
    {
        if (instance != null)
        {
            Debug.Log("You have two instances of " + gameObject +" mono singleton!");
            gameObject.SetActive(false);
            Destroy(gameObject);
        }
        else
            instance = (T)this;
    }
}

public class BulletsManager: MonoSingleton<BulletsManager>
{}

Here we can’t make the constructor private or protected – this is a monobehavior. So instead you may want to destroy any additional monobehavior that gets created, and warn the user about this.

The awake function is marked as virtual. If you haven’t encountered this word before, it means that this function can be overridden by any class inheriting MonoSingleton (its “children”) if they want to. So virtual is a bit like “check if my children have changed the behavior of this function”. The children will simply have to declare the function again and replace “virtual” by “override”.

You will note that this is a bit different from the precedent case: what if you haven’t added this mono singleton to the scene? Well, it will crash. Not cool eh? So we need to do two things:

  • add an error message before it crashes in the Instance.get. This will be useful for simple MonoSingletons that are mandatory in the scene. Make the message meaningful, because your designers will be the ones reading it. Something like: “Hey Mike, you forgot to add a Bullet Manager to the scene”.
  • create a special mono singleton that can instantiate itself if it is not in the scene. This will be useful for objects that you may want to have sometime in your scene, but not always. They need to be OK to load from disk and create a small stutter. A special UI error message would fit for instance: as the player unplugs the game pad, you want to display your UI error message. This is unlikely to happen every time, so it is the perfect case. As you will pause the game as soon as the player unplugs the cable, it is OK to have a 1s stutter while the MonoSingleton is loaded and instantiated.

This second MonoSingleton will be a bit different:

public abstract class  MonoRobustSingleton<T> : MonoBehaviour where T : UiSingleton<T>
{
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                string fileName = "Prefab/MonoSingletonPrefabs/" + typeof(T).Name;
                GameObject newSingleton = (GameObject)GameObject.Instantiate(Resources.Load(fileName));
                return newSingleton.GetComponent<T>();
            }
            return instance;
        }
    }

    protected static T instance;

    protected virtual void Awake()
    {
        if (instance != null)
        {
            Debug.LogError("MonoRobustSingleton " + gameObject + " is instanciated twice.");
            Destroy(this);
            return;
        }

        instance = (T)this;
    }
}

public class PadDisconnectedErrorMessage: MonoRobustSingleton<PadDisconnectedErrorMessage>
{}

We still have the static instance, and the error messages in the Awake function to handle unexpected scenarios. But the instance creation is different: we load a prefab from the resources folder. We could go the easy way and create a GameObject and add a component T to it. The issue though is that your MonoRobustSingleton will often need other components and some children to work. So we force the user to create a prefab, name it PadDisconnectedErrorMessage and store it in the Resources folder. This folder is a bit magic: whatever file is placed inside it will be taken by Unity upon building your game. It will be accessible later for hot loading, even if no one references it explicitly. The files in the other folders will only be included in the built if they are referenced somehow by an object in your scene. So our MonoRobustBehavior prefabs are safe in this resource folder! They will be lazy-loaded whenever needed (lazy in the sense “only done if required, not loaded by default).

Conclusion

The mono behavior singletons are not as safe as the classical singleton, nor as easy to use, but they remain a very powerful system. For our game, we based our UI system on MonoRobustBehavior: we wanted to load the bare minimum UI with the scene, to speed up loading times and allow higher modularity (ie: call any UI screen when you need it, no matter the context or the scene setup). So when you press “pause” or go through the menus, we hot load the UI as required. Although the framerate does go down whenever a new page is drawn, it is impossible to tell the difference. It would be visible though if we used it to load enemies for instance, as a small lag is much more noticeable when you move a character in real time than when you press a button to go from a menu page to another. But it saved us a few seconds of loading screen on our game! (we have simple scenes but heavy UI).

Anyway, I hope this post will help you with singletons! I know some people find them overused, but for simple projects I find them perfect and easy to understand. If you have any comment, disagree or even think I am Hitler reincarnated, leave a comment!

Social media frenzy

Game Music: Recording and Mixing the Soundtrack of your Game

Deciding what kind of music you want for your game is tough and sometimes you end up with some kind of soundtrack that doesn’t add any value to your gameplay.

I guess it all depends on personal taste, however it’s always important to understand the type of feeling you want to convey to the players out there. People are eager to have a new experience with every new game they buy in this time and age, especially among the Indie environment where Audio is as important as Arts and creativity and originality is truly rewarded. I like to call it the Renaissance of Computer Arts :D.

My name is Gabriele and I am the Composer and Audio Director at Space Lizard Studio Ltd. I was influenced by video game music since I was a kid and had my Commodore 64 up and running. I’ve always tried to adapt the music I’ve composed to the mood of the games we were developing, as I wanted to put myself in the user’s shoes and get the best experience out of it.

The current project we are working on is a Run & Gun game called Dragon Bros featuring 4 teenage dragons with guns, that’s right dragons and guns, explosions, fun, chaos. I want fun in my soundtrack, I want chaos, I want a fast paced burst of adrenaline. Hey! It’s a retro-Pixel art game…I want chiptunes and rumbling guitars! Something like this:

IntroFrame 01

This track is still work in progress and not equalized yet. So let’s talk about equalization!

You have two challenges here: Distorted guitars and high pitch chiptunes. Equalizing those to optimal settings is a pain so here’s some useful tips that may help you out in future if you ever decide to crazy mix these two things together.

Guitars

First, get the sound you like for distorted guitar by tweaking your effects, plugin or pre-amp. After, and only after, start thinking about EQ (equalization).

If you want punch and impact you may want to boost 70-90 Hz frequencies and set highpass to 50 Hz.

Spend a lot of time in tweaking anything between 150 and 700 Hz as this will define what’s the “glue” of your instrument. If you use multiple guitars and want to make some of them more clear, then play around the 2 kHz area as you like.

If guitars get way too bright, try to cut a bit the 8-10 kHz so it doesn’t clash with your high pitch chiptune effects. It is very important to remove the hissing sounds as much as you can, so you may want to cut a bit the 3-4 kHz category too.

I find it useful to record at least 4 tracks of the same guitar at once if you want that wall of background heaviness in your chorus. I use these Pan settings for my multi track guitars:

1- 90% Left mid-low frequencies.

2- 90% Right mid-low frequencies.

3- 60% Left mid-high frequencies.

4- 60% Right mid-high frequencies.

Polish everything with a last touch of compression to get rid of hissing noise and dodgy frequencies, not too much though.

CHIPTUNES

These SFX (sound effects) may be highly annoying overtime. Trust me, you don’t want them to drill your brain constantly for several minutes.

Best way to make them less annoying is to make the higher harmonics less intense, as they are super bright. 10 kHz – 14 kHz – 20 kHz, put them way below 0dB, and raise 55 to 800 Hz keeping whatever is between 1.2 kHz and 5 kHz at mid level.

This will kill that harsh effect in some parts making them sound better in the mix with guitars.

My last work for a level – meant to be inside of a Crystal Cave – features a lot of different chiptunes mixed with guitars and breakdowns and a bit of darker moments and echos. I am still not entirely satisfied in regards to the percussion yet, but this sample can give you an overview of the EQ I am trying to harmonize in the Mix.

Caveconcept02

I hope you found this post useful and if you have any thoughts or suggestions to share, feel free to comment down below or reach us on Facebook!

Wishing you the best,

Gabriele Caruso

Social media frenzy

2D game graphical assets workflow: how to be efficient

Hi there, this is Marco, Art Director from Space Lizard studio!

Today I wish to share with you my personal opinion on pixel art creation process for video-games. This is the method I use in order to quickly visualize concept art and produce assets.

Due to the short development time we have chosen for Dragon Bros, I need to skip the hand drawing concept process. Instead, I use a more direct approach that gives me more time to refine and polish the final assets used later in game.

Everything starts with a canvas

Because I want to know immediately if something will look good in game, I usually create a canvas that has the same pixels size as the game resolution.

01

Chose a colour palette

Usually, it is a good idea to gather inspiration from other products: pictures, movies, other video games and so on. Or, if you feel confident, you could use some online tool that will make your life much easier.

For instance, Adobe offers a free service that helps you to browse colors and create your own palette:

The Adobe color-wheel.

Palette

Paint on a color

The background should be filled with a color before starting painting the assets. There’s a good reason for it: the background color will strongly modify the perception you have of the colors on top of it.

Try to paint the same red on a white canvas and on a mid grey canvas. Put them next to each other. It will drastically change your perception of the luminosity and general tone of the color.

Since we do not want any surprise when the asset are placed in the game, it’s best to use a unique background color: the one you will use in game (sky, etc).

Start from the bottom.

It is tempting to start painting the elements and decorations we imagine first in the scene. But to achieve a coherent look among our assets, it’s always better to start painting the biggest portion of the screen space.

In Dragon Bros we decided to use one to four parallax layers. Because of that I usually start with the background layer which is nearest to the camera and will give the direct contrast to the items in the Character layer.

02 03 04 05

Always use and organize your layers

When painting assets and backgrounds, keep in mind that what you are painting will be the actual asset exported to the game. You will need to export them individually, so don’t paint everything on the same layer!

Keep your layers organized and clean, invest time to keep your scene clean and it will repay later, during the exporting process. Like a lot.

Also, use groups as much as possible. They are very useful to keep the animation’s frames organized and different objects drawn on multiple layers.

Keep it simple

Part of the beauty of the pixel art is that it is based on the overview: simple details that build a very complex scene.

You shall reflect this idea in the way you think your assets. Don’t over-complicate small details. Make simple things that are themselves little simple details for the biggest context.

Animations

Animated scenes reflect best what the game will look like eventually. So animate it!

Then move your assets around and always focus on the context. Does it still feel good?

When building your level in your game engine, chances are that objects will be moved around – again!- for gameplay or esthetic reasons. So you need to double check this and build a few different combinations.

Animating is long, but here’s the good news: you don’t need long animations to make it look good. Four to eight frames are usually enough to give a nice feeling. Of course, it is totally fine to do more if an object requires it!

output_fndt2Y

Polishing and Exporting

I find this part to be the most time consuming: you need to isolate the frames and assets in their dedicated textures in order to export them to your game engine. Of course, this process will take advantage of a good layer organization during the painting process (see previous part!)

This step will reveal all the defects that were hidden by the overlapping layers, so take your time and polish all the imperfections you may spot.

Export your textures and you are ready to create your in-game assets in Unity!

Social media frenzy

Unity: a guide to moving platforms in 2D

Hi everyone! Today we would like to share with you our experience with moving platforms and physic based character controller in Unity.

This is an basic / intermediate tutorial. We will assume you know a bit of C#.

The problem

I will take as an example the elevator that our team has designed to allow our Dragon Bros to reach the lower levels of the mining facility.

The first approach was to create a Gameobject with a BoxCollider2D, a Rigidbody2D and an animator. We also added a custom script to it, to keep track of the elevator status: waiting or moving.

The lift starts moving when one of the character triggers a designated collider (typically when entering the elevator’s cage).

Finally, an animation controls the movement of the lift, by simply changing the position of the elevator.

First problem

The elevator’s movement is shaky. It doesn’t matter if the character is on it or not.

First solution

Do NOT animate a rigidbody position. It is best to use RigidBody.MoveTo, so the rigidbody can compute the exact force needed to move to a position in one frame, by countering gravity, friction and inertia.

Once this is fixed, we encountered…

…A second problem

The resulting lift correctly moves, but the character is falling for a couple of frames, reaches the platform, collides with it, and then again fall again in an endless loop. It looks terrible and flickers.

ElevatorIssue

And a second solution!

To solve this issue we decided to implement a SliderJoint2D to constrain the position of character on the y axis(vertical one).

void ConnectTo(Rigidbody2D character)
{  
  SliderJoint2D joint = GetComponent<SliderJoint2D>();
  joint.connectedBody = character;
}

void OnCollisionEnter2D(Collision collision)
{
    if (collision.collider.gameObject.layer == LayerMask.NameToLayer("Character")
    {
        ConnectTo(collision.collider.GetComponent<RigidBody2D>());
    }
}

The slider is connected to the character RigidBody2D as soon as the character collide with the elevator. Now the character is not falling / flickering anymore, but the character has lost the capabilities to jump!

The solution to this is to create an event to be invoked when the player press the jump button. When the event is called, we release the slider. We will reconnect it when the character lands again on the platform.

void Connect(RigidBody2D  character)
{
    ...

    // listen to the character jump event
    character.GetComponent<CharacterController>().onJump += OnCharacterJump;
}

void OnCharacterJump(CharacterController character)
{
    Disconnect(CharacterController character);
}

void Disconnect(CharacterController character)
    // do not listen to this anymore
    character.onJump -= OnCharacterJump;

    // disable the joint by unplugging the character
    joint.connectedBody = null;
}

Similarly the slider is removed when the player walks away from the platform.

void FixedUpdate()
{
    if(joint.connectedBody != null
    &&  Mathf.Abs(transform.position.x - joint.connectedBody.transform.position.x) 
        >= kBreakingDistance)
    {
        Disconnect(joint.connectedBody.GetComponent<CharacterController>());
    }
}

Now the character is constrained on top of the elevator. But it also is when colliding with its bottom or side! To solve this issue we will add a check on the direction of the collision.

void OnCollisionEnter2D(Collision collision)
{
    if (collision.collider.gameObject.layer == LayerMask.NameToLayer("Character"))
    {
        Vector2 direction = collision.contacts[0].normal;
        if (Mathf.Approximately(direction.y, -1f))
        {
            ...

And now the position of the character can be adjusted by properly setting the anchor point of the slider before connecting the two RigidBody2D.

// upon collision, record our distance and use it as an offset.
joint.anchor = new Vector2(0f, Mathf.Abs(transform.position.y - character.transform.position.y));

It looks better, but we still face a subtle flickering in the character and the platform.

We tried to decrease the Physic TimeStep to 0.01f instead of 0.02f and it actually made this issue less noticeable, but still visible and also lowering the overall performance. It was not a real solution, just hiding the problem!

We also tried to the change the physic material to increase the friction and zeroed the bounciness, made sure to move the lift RigidBody2D with the method RigidBody.Moveposition() and also increased its mass but the flickering remained.

A bit desperate, we tried parenting the character to the elevator, which kind of worked but raised other issues. Disabling the collision between the elevator and the character kind of worked as well, but proved unnecessary later.

Final solution to the flickering

The flickering is due to the opposite forces being applied by the slider and the collider of the platform counterbalancing the weight of the character, plus the approximation made by the physic engine.

To solve the problem, we nullified the gravity scale on the character as soon as it collides with the elevator and store it. When it disconnect, its gravity scale is set back to its stored original value.

And there you go…. we now have the perfect elevator!

THE FUTURE

Local multiplayer

If you have two players or more sharing the elevator, you will probably encounter problems with the previous code!

The solution is pretty simple: have one slider joints per player. Store them in a table and store the players in another table. Surround the code with a few loops, you’re done!

Complex cart movement

Maybe you want your cart to stop midway, as if temporary out of order? Or you want it to go very fast suddenly, as if the brakes are giving up? There are many ways to do this. The one we chose was to have a list of waypoints, each assigned with a speed and an optional wait. We created dummy game objects in our scene, named “Elevator Waypoint 1”, etc, and assigned them to the elevator’s list of waypoints.

Super mining cart

This lift is the first step towards… a mining cart of course! Now that you have locked the vertical movement, you will simply need to lock the horizontal one as well, with a slider joint at 90 degrees. This system combined with the cart movement will allow you to easily create crazy mines levels!

Social media frenzy

Unity: how to design a simple checkpoint system

Hi everyone, today we would like to share our experience about Checkpoints in Unity. As we are developing a 2D platform game, it soon came to us that using checkpoints was mandatory.

Note: This is a beginner guide, if you are an intermediate or advanced Unity user, this will probably be a bit too detailed for you.

The basics: creating a checkpoint

It’s super simple: create a game object. Place it where your checkpoint should be. You probably want to make it visible somehow (flag, life stone, etc) : add a sprite renderer or a mesh renderer.

Then you want to add a collider to it. It is tempting to make it match its graphic renderer. Do not: what if a player jumps above it? Or ducks underneath it? Unless it is part of your gameplay, make sure to make it so large that it can’t be avoided as the player progresses through the level.

The collider needs to be set to trigger of course, so your player can pass through it.

You may want to play an animation when the player goes through it : the flag goes up, the life stone shines, etc. As usual, add your animation controller and your three animations (non-activated, activating, activated for instance).

You will also need to create a custom script and attach it to your new game object. It will probably look like that:

using UnityEngine;
using System.Collections;

public class CheckPoint : MonoBehaviour 
{
    // have we been triggered?
    bool triggered;

    void Awake()
    {
        triggered = false;
    }

    // called whenever another collider enters our zone (if layers match)
    void OnTriggerEnter2D(Collider2D collider)
    {
        // check we haven't been triggered yet!
        if ( ! triggered)
        {
            // check we actually collided with 
            // a character. It would be best to
            // setup your layers so this check is
            // not required, by creating a layer 
            // "Checkpoint" that will only collide 
            // with characters.
            if (collider.gameObject.layer 
                == LayerMask.NameToLayer("Character"))
            {
                Trigger();
            }
        }
    }

    void Trigger()
    {
        // Tell the animation controller about our 
        // recent triggering
        GetComponent<Animator>().SetTrigger("Triggered");

        triggered = true;
    }
}

Non triggered:

Checkpoint1

 

Triggered:

Checkpoint2

Phase 2: Detect character’s death

We will assume you have a “Death” function in your character controller. We want to be warned of the character’ death. An easy way to do this is by using an event. It is much cleaner than polling, which could be summed up to “Every frame, check if character is dead”. So create an event “OnDeath” in your character controller:

public delegate void MyDelegate();
public event MyDelegate onDeath;

And call it upon death:

void Death()
{
    onDeath.Invoke();
}

Now in we will modify the Checkpoint’s Trigger function to subscribe to this:

void Trigger(Collider2D collider)
{
    CharacterController character = collider.GetComponent<CharacterController>();
    character.onDeath += OnCharacterDeath;
    ...
}

void OnCharacterDeath()
{

}

That’s it! OnCharacterDeath will be called whenever the Death() function is called.

Phase 3: pass the death information

Now we need to notify your enemies, bonus crates and such that they should reset to their initial state. Create a new script called RespawnController. We will attach this script to every object requiring respawn notification.

using UnityEngine;
using System.Collections;

public class RespawnController : MonoBehaviour 
{
    public CheckPoint respawningCheckPoint = null;

    public delegate void MyDelegate();
    public event MyDelegate onRespawn;

    Vector2 initialPosition;

    void Awake()
    {
        initialPosition = transform.position;
        respawningCheckPoint.onRespawn += OnRespawn;
    }

    public void OnRespawn()
    {
        transform.position = initialPosition;
        onRespawn();
    }
}

This script will position the objects back to their initial position. Every component of your enemy should also subscribe to the RespawnController.onRespawn event to deal with their internal resetting needs: your enemies should get their hit points back, your puzzles should reset, etc.

This means that your enemies and crates shouldn’t destroy themselves upon death, but rather go dormant (using gameObject.SetActive(false) for instance) so they can be respawned easily.

You will need to assign manually every enemy’s checkpoint in Unity. I strongly recommend adding a check in your RespawnController’s awake function:

if (checkpoint == null)
{
   Debug.LogWarning("You forgot to assign a checkpoint to enemy " + gameObject.ToString());
}

This will help you find the few enemies you may have forgotten to attach to a checkpoint.

Multiple checkpoints

Now you will want more than one checkpoints of course! And only the current checkpoints’s enemies should be reset! So we need a way to know which checkpoint has been activated last.

So let’s create a checkpoint manager! Create a new GameObject “CheckpointManager” and make sure your checkpoints are its children.

Create a CheckpointManager.cs script and attach it to your newly created checkpoint manager object:

public class CheckPointManager : MonoBehaviour
{
    public List<CheckPoint> CheckPoints { get { return checkPoints; } }
    public CheckPoint CurCheckPoint { get { return checkPoints ? checkPoints[curIndex] : null;}}
    public static CheckPointManager Instance {get{return instance;}}

    List<CheckPoint> checkPoints = new List<CheckPoint>();
    int curIndex = 0;
    static CheckPointManager instance = null;

    protected override void Awake()
    {
        instance = this;

        // find all my check points children
        for(int i = 0; i < transform.childCount; ++i)
        {
            CheckPoint checkpoint = transform.GetChild(i).GetComponent<CheckPoint>();
            checkpoint.onTrigger += OnCheckPointTriggered;
            checkPoints.Add(checkpoint);

        }
    }

    public void OnCheckPointTriggered(CheckPoint newCheckPoint)
    {
        curIndex = checkPoints.IndexOf(newCheckPoint);
    }
}


Now in the Checkpoint’s OnCharacterDeath function, you can decide whether or not you should reset your list of enemies:

void OnCharacterDeath()
{
    if (CheckPointManager.Instance.CurCheckPoint == this)
    {
        onRespawn.Invoke();
    }
}

Tadaa! You do not need to worry about your whole level resetting upon death, only you latest part will.

Note: you may be like “WTF is this static Instance mumbo jumbo doing here”. Bear with us, next week we will tell you more about the mighty power of the Singleton!

Some random diagram

Here is a short diagram of what we just wrote:

CheckpointDiagram

The CheckpointManager holds the checkpoints list. The CharacterController notifies the Checkpoint. In turn, it notifies the enemies, crates and puzzles.

And much more…

Now you have a basic checkpoint system. But I am sure you will want to have extra stuff added! This will probably depend on your game design, but you will easily implements those:

  • Checkpoints can be triggered more than once, so the character can navigate backward.
  • Optimize the number of active enemies on screen by having them to be SetActive(false) until their checkpoint is activated. This can save a lot of CPU!
  • Deactivate enemies that belong to older checkpoints, still optimization.
  • Optimize your level restart: no need to reload the whole scene if your checkpoint system is robust!
  • handle local multiplayer checkpoints.
  • Add a debug menu to teleport to another part of the level. This will greatly help you test your game! But make sure to surround the code with
#if DEBUG

// debug code

#endif

so you do not publish those debug tools!

  • use those checkpoints as a save point, so the level can be played from there again next time the game starts.

 

Have fun! And please leave a comment here if you have a question, found an error or even totally disagree with us ūüėČ

Social media frenzy