Persistent Game State and Switching Scenes – Memory Leaks and Crashing!

TitleScene

So I wanted a really cool menu scene where I have actual characters from the game and a 3D world as the backdrop.  You can see the image above for an example.  When you click New Game, the camera zooms in on a single character with the others slightly out of view on either side but still visible.  Swiping left or right takes you to the next character you can choose.  While you are on a character, you can interact with the character via normal input, switch between attack and spell phases, create a minion etc.  These characters are powered off of the same state management system that centrally controls the state of my game.  This same system also includes my event management system, which is also persistent.

The Two Script Solution

OK, so maybe I should have two completely separate scripts, one for the menu character controller and one for when you are playing the game.

But that solution doesn’t actually fix all Scenarios

Imagine the scenario where you are in a Scene “Level 1”, and you load “Level 2”.  What happens to your characters is that Unity destroys them.  But they were listening to all of your events.  So now your event manager has references to events that don’t exist anymore and is going to try to fire those off.  This should crash your game.  In some cases in Unity, especially if you are instantiating your character or bullets or whatever, it enters what I like to call the “I did something wrong Loop”.  This loop it just keeps instantiating stuff and you end up with thousands of copies of your prefabs (in my case spawning zombies :)) that then crashes your dev box.

If you somehow by miracle manage to have done enough null checks and survive both of those scenarios, you have yourself a nice memory leak because as you change scenes and go between menus, you are constantly adding new events and not removing them and the Garbage Collector will not be able to collect any of the objects and release the memory of the objects you are hanging onto references to, even though they may be destroyed.

Ok, so that was a ton of doom and gloom, what do we do about it?

MonoBehaviour has a nice event you can listen to called OnDestroy().  Make sure you remove your references to that.  So at this point in my game development of this particular game, I am only ever listening to one event, but will add more.  Below is what you should do.

Adding an Event

When adding an event it is specific to this instance of my script.

    private void Awake()
    {
        this.movementScript = GetComponent<CharacterMovement>();
        GameStateManager.Instance.GameStarted += new GameStateManager.GameEvent(this.OnGameStarted);
        this.internalMovementRadius = (this.movementRadius / 2) * (this.movementRadius / 2) - 30; //30 just happens to be one of those magic numbers.
    }

Removing an Event

When removing an event, it is specific to this instance of my script.  Note if you add your event twice, you should probably just only add it once and fix that problem instead of removing it twice.

    private void OnDestroy()
    {
        GameStateManager.Instance.GameStarted -= this.OnGameStarted;
    }

Summary

So there you go.  Persistent Game State Management is very crucial and important, but you still need to manage it properly.  This is just one item to be aware of.  I’ll probably encounter and think of more as I go.

One thought on “Persistent Game State and Switching Scenes – Memory Leaks and Crashing!

  1. cheap ralph lauren hoodies”.. cheap ralph lauren
    ralph lauren tracksuit cheapIn recent years, the NCAA Men’s basketball tournament has become widely popular. Therefore, it is one of the most watched, most anticipated, and most widely talked about sporting events in the United States. There is no telling whether or not the tournament will continue to increase in number, or if it will stay the same. york outlet ralph lauren

Leave a Reply

Your email address will not be published. Required fields are marked *