6. Doors & Keys

In this part, we'll implement the new challenge in level 2: opening a door with a key. Start by opening the level 2 scene, which already contains the setup and prefabs.

1. Add a HasKey variable

When the player reaches a door, we'll need to check if they have a key. For this purpose, we'll use a boolean (true / false) variable on the player.

  1. Select the Player object
  2. Add a new boolean object variable called HasKey, default to false
  3. Apply the changes to the prefab so other players share this variable

2. Create the key flow machine

When the player collides with the key in the scene, the HasKey variable should become true, and the key should disappear. 

  1. Select the Key object
  2. Add a new flow machine
  3. Convert its source to a macro called Key
  4. Apply the changes to the prefab

The graph is really simple now that we can reuse our On Collision With macro:

Destroy is located under Codebase > Unity Engine > Game Object. It's important to note that unlike most functions, this one does not automatically take Self as its target, which is why we must explicitly connect a Self unit.

3. Create the door flow machine

Here we go again:

  1. Select the Door object
  2. Add a new flow machine
  3. Convert its source to a macro called Door
  4. Apply the changes to the prefab

In the graph, we'll check the HasKey variable on the player. If the key is found, we disable the box collider on the door and change its sprite to look open. If the key is missing, we just output a message to the console for debug.

  • Set Enabled is located under Codebase > Unity Engine > Box Collider 2D
  • Set Sprite is located under Codebase > Unity Engine > Sprite Renderer
  • Log is located under Codebase > Unity Engine > Debug

If you test your game now, the door should open only if you've grabbed the key:

4. Display the key in the HUD

The last thing we have to do is to handle the HUD display for the key. 

When the player grabs the key, the empty key icon should become filled.

If there is no key in the scene, the key icon should be hidden altogether.

  1. Open the HUD scene
  2. Select the Key object under HUD > Row
  3. Add a new flow machine, leave it at embed

We can leave the machine at embed because we will only ever use this graph once, in the HUD scene. In other words, there is no need to create a reusable macro because the HUD is not a prefab.

To hide the key icon if no key exists in the scene, we can set the game object to inactive if there are no game objects tagged with Key:

  • Find With Tag and Set Active are located under Codebase > Unity Engine > Game Object
  • Null Check is located under Nulls

To change the sprite depending on whether or not the player has the key, we need to check the HasKey variable on the Player object:

You can find the sprites HudKeyFull and HudKeyEmpty under Sprites / HUD.

There is a small performance problem with our graph: Find With Tag is known to be a bit slow. It's not an issue if we only use it once on Start, but since we're calling it every frame in Update, it would be ideal to use a faster way to find the player. This is slightly premature optimization (our game would run perfectly fine with Find With Tag), but we'll show it for the sake of teaching "best practices".

We'll use a application variable called Player and holds a reference to the player game object. It will get automatically created by the player graph, so we won't need to set it up in every level manually. This is a simple implementation of the "singleton" pattern: because we know there's always only 1 player in the game, it's safe to assign its instance to an application variable.

Important Update Note: Prior to Bolt 1.2.2, we were using a scene variable for this part of the tutorial (some screenshots have yet to be updated). However, the way scene variables are handled has changed and we now need an application variable instead. Basically, scene variables can no longer be accessed from other scenes than the current one, and because the HUD needs access to the player, we need an application variable to access it across scenes.
  1. Save the HUD scene
  2. Open the PlayerController flow macro
  3. Add this group of units somewhere in your graph:

Now that this is done, we can go back to our HUD key graph and replace Find With Tag by Get Application Variable:

That's it! Now, if you test your game, you should see the key sprite change in the HUD:

Head-Up Display (HUD) Health & Damage

This article was helpful for 14 people. Is this article helpful for you?

In step 4, HUD key's scripts are there, tutorial maker forgot to del them :D


Wouldn't it be better not to run update sprite graph every update, but fire an custom event when we collide with the key?


A little bit yes! But because this game is not at all performance intensive the tutorial opted for simplicity over optimization. There are multiple ways of doing any task in Bolt, and an event would work as well.

Just one thing, when you open the door the key sprite remains full. Shouldn't it be the "keyempty" again or even disable the object? (like when you check if there is any key available in the scene)..


Well, in that case, there's only one door and key, so HasKey doesn't get reset when you go through the door. You could modify the door script to set HasKey to false after opening it if you wanted the 1 key = 1 door logic!

Alright! Thanks Lazlo!


Get Scene Variable is not working for after I made the Singleton. I'm using version 1.2.2. Notice that the Scene Variable is indeed set, but I cannot access with Get Scene Variable from the HUD scene Flow Machine.

The error is

InvalidOperationException: Variable not found: 'Player'.
Bolt.VariableDeclarations.Get (System.String variable)
Bolt.GetVariable.Get (Ludiq.Recursion recursion)

Got the same error. What I did to "solve" it was to make the Player variable an App Variable. Don't know if it's the best solution, though.

To make this "solution" work you have to make every Get Variable "Player" an App.

D'oh! That's my bad. Isolated scene variables in v.1.2.2 make it impossible to access the Player variable because it's defined in another scene. The correct way to do it is indeed to use an Application variable instead. I'll update the tutorial soon.

Edit: Added a warning in the mean time!

For me I made HasKey an App Variable  went back over all Items and change the Get Variable  to Get App Variable  once done on the Key Door & Player all worked but have now you have to reset that when you change levels  ;)

Ok. On the latest version.

So sorry I am missing something. Does both the Player and HasKey both now a 'Application' type or is one left as a Object. But ether case, when you hook one to the next and then to the Select it removes the HasKey value.

Don't worry. I see what I was doing wrong. So when we do a Start>Get Variable on the Player to get itself. And then on another object we do a Get Variable> Player. Is this a By Val to the object. That is we change this anywhere it will change for all that do a Get Variable or is it a ByRef (snapshot at the time we do a Get Variable) when then grab values from the GameObject after we Get Variable Applications>Player

So  iapplication variables are global variables? Is there any other way to access a variable on another object/ flow machine? Somehow helping to split up graphs?

I tried changing Scene Variable to Application Variable, and the error no longer appears.

Since Application Variable can be referenced throughout Unity, we could access even in another scene.

I got it to work by creating the Singleton and changing all the calls to HasKey variable to be Application instead of Object variables. However, when I enter Level2, I get an error:

InvalidOperationException: Variable not found: 'HasKey'. Bolt.VariableDeclarations.Get(System.String variable)

This error appears 3 times. Could this page of the tutorial be updated please to the newest standard so we can get through it without errors and confusion? I'm stuck here and would love to continue.

Seems like this page is not up to date, it doesn't work and the update note at the end is confusing. Could you redo this part of the tutorial so it can be followed without errors and confusion? I'd love to continue.

Are you  sending your node into the HasKey( get variable) string? And not the game object? Beginner here so I’m blindly trying to help. I do it all the time as well.  Read the error from the graph inspector instead of the console, might be more helpful to fix the issue.

I don't know, it's all so confusing to me. Now I fixed that error somehow, but my Death group is not reloading the level when I fall on the spikes. I think it will just take some time for me to get over the learning curve, as I just started using Bolt 2 days ago. Thanks for answering.