A project idea (and some dead ends)
If there's one thing that my kids associate with Christmas, it's Lego! More so than turkey, mince pies or a tree - it's often all about Lego. They tend to get at least some Lego as a present and they're currently still enjoying playing Lego Star Wars Xbox games from last Christmas.
At the moment, some of my focus is on getting to grips with the Unity and Unreal game engines. I've been involved around the edges at work when both Unity and Unreal were used by another company to create a UI to go in front my work. I've also been playing around with VR for the same reasons.
Lego and Unity
It's always good to find a project that can push you in the right direction when learning new stuff, so I thought long and hard about whether I could combine Christmas, Lego, game development and of course some electronics. Luckily, as I was busy getting to grips with the basics of Unity, I came across their Lego Microgame tutorial. I can thoroughly recommend it. The Lego brick concept wraps nicely as an abstraction over some of the Unity processes. It's a great way to simplify game development and to give you some of the building blocks to create on your own. There are a few oddities if you do know a bit of Unity. It can be tricky when some of the stuff that you know works without the Lego components no longer works as you expect. All in all though - it's a good starting point.
So, there's a way to combine Lego and game development. Two down and two to go. How about adding VR and electronics? I decided that the electronics side should involve bringing the game play out to the real world. When something happened in the game I wanted something to happen in the real world. Turn the Christmas lights on in the game and I turn the Christmas lights on in the room. That sort of thing. It seemed a reasonable goal. I'm familiar with coding in C# so I assumed it wouldn't be too hard to connect out over USB and switch a relay or two.
So, then I started looking at the VR side. You do this by adding a camera in the game that essentially film's it from the position of your headset. As you move your head, the view of your game world changes with it. Then you can add a mechanism to teleport around if you need to. This experiment went well - but with two minor issues. Firstly, I seemed to have got the scale wrong and I created a strange dystopian world inhabited by 15ft tall Lego minifigures. The Lego player figure was were still under control of the keyboard / Xbox controller which meant it could run around independently in the same world as the virtual you.
This was a lot of accidental fun. I added the VR teleport functionality and I now had a "game" where someone could move around in the Lego world and someone else could control a giant Lego figure which chased them and tried to jump on their head. terrifying but amusing. However this made me realise that the immersion in the VR world cut the player off from any physical interaction with the electronics. I know I can combine Lego and VR, but maybe I'll save that for another project.
I opted to continue the game without VR and decided to work out how to interact with the physical world. A serial connection to a USB capable microcontroller was my first thought. I could use a relay to switch power to something. Of course it's always safer to switch the low side (12V) after any wall wart than switch mains going into it. Then it hit me! I could use my Keysight E36312A power supply instead of a wall wart and use SCPI control over Ethernet to do the switching for me! The first thing to do would be to check that I can indeed control my power supply from within Unity. Here's a quick test to make sure that I can control the supply from C#. I'm using Visual Studio and I've written a simple test console application.
Once things looked good in desktop C# it was time to move it over to Unity. Unity uses the Mono runtime rather than .NET Core so there's a chance it wouldn't behave the same and I needed to make sure my code was still valid. Here's the test Unity C# script I came up with. This script can be attached to a game object and triggered from within the game. The methods On() and Off() simply set channel 2 to 12V / 1A and then either enables or disables the channel. I attached it to my "you won" scene so the Start method (which is called after a game object is created) turns the power supply on. The Off method is then called when you click "play again".
public class ScpiControl : MonoBehaviour
const string HostName = "K-E36312A-80260";
public void On()
public void Off()
private void SetPower(bool on)
TelnetConnection tc = new TelnetConnection(HostName);
// Set voltage and current on CH2
tc.WriteLine("SOURCE:VOLTAGE 12, (@2)");
tc.WriteLine("SOURCE:CURRENT 1, (@2)");
tc.WriteLine("OUTPUT:STATE " + (on ? "1" : "0") + ", (@2)");
Console.WriteLine("Error opening " + HostName);
catch (Exception e)
On with the game
Whilst I could describe in detail the process of creating my own Lego game, I feel you'd be better served by following along with the excellent guide that Unity and Lego have created. Suffice it to say that you can do the following:
- You can build with existing Lego bricks in your game.
- You can build more complex Lego creations in Bricklink Studio and then import them.
- You can add behaviour to your models with action bricks or scripts.
I did hit some issues along the way. The scripts created by Lego don't attach well to smaller Lego pieces - like a minifigure sized carrot for Rudolph - as they're designed to work with studded bricks. The scripted Lego functionality can also interfere with standard Unity functionality. For instance, I tried adding trigger colliders to Lego models but the functinality provided by these in vanilla Unity was overridden by Lego scripts. Multiple steps in a level (such as "Speak to Mrs. Claus" and "Find some snacks") and are handled for you, but this means that it's hard to reveal hidden parts of the level as you go along. To be honest these little issues seem fair enough considering what you get out of the deal. I just know I can do this easily in "baremetal" Unity.
All-in-all the game creation experience was a satisfying one, but it was even better to see the two normally distinct worlds of video games and test equipment come together! I suppose you're wondering exactly what my SCPI controlled power supply was hooked up to? All will soon be revealed!
So, here's a video of my 9-year-old son playing through the game. When he first played, the appearance of Santa and Rudolph was a surprise. He was so focused on the game he didn't notice me sneaking in to place them behind him. When he got to the end of the game he wasn't expecting a video game to cross over into the real world.
However, these days all kids seem to want to be a YouTube gamer superstar, so at his request we re-recorded the video and you now get the benefit of his in-game commentary instead. The game was created for him and his brother, so who am I to say which version was better! (It was the first one.)
If you'd like to try the game yourself it's available as a WebGL game at https://play.unity.com/mg/other/webgl-s6j Can you make it to the end? Can you spot the fairly obvious elf14 Easter egg in the second level? (Surely it's the wrong time of year for Easter eggs.) I thought about being a bit more subtle by just adding 14 elves but it got a bit crowded in there!
The source is also available at https://github.com/FredMurphy/LegoChristmasGame if you'd like to take a closer look or even tweak it yourself. Maybe you've got your own SCPI controlled hardware that you want to incorporate into a video game. It certainly adds an extra dimension!
Post Christmas update
They got lots more Lego this Christmas - including a Ducati Panigale V4 which I must admit I was a little bit jealous of. They may have moved a bit more towards Lego Technic this year, but Lego is still a firm favourite and I'm sure it will be for years to come. They'll still ask to play this Lego game sometimes, but Santa and Rudolph are now back in the attic until next December.