Blissful unity

Regular readers of this blog will note that 2019 has not been a particularly fecund time for new posts. This is principally due to my getting married recently – typically weddings are events with minimal overlap with the kind of topics I write about here. Unless, of course, one of the people getting married happens to be me.

Weddings are a great chance to inject a bit of your own personality into proceedings, with a captive audience who have no choice but to go along with it. My wife and I are (surprise, surprise) pretty geeky people, so of course there were the requisite science references at dinner and classical covers of video game scores throughout, but here I’ll chat about my additional contributions, done more for my own amusement than any particular utility.

A bit of data

First, for the data enthusiasts, a quick summary of the first thing people usually ask you about when you say you’re getting married – the cost. The total cost seemed to be around the UK average, which would get you a pretty good car, a mediocre x-ray camera, or a disappointingly-specced Mac Pro.

The percentage breakdowns are below, and in hindsight our priorities were very clear – ensure everyone ate and drank very well, in a venue which looked great, wearing some fancy rings!

The app

My chosen method of injecting some uniqueness to my wedding was to write an app. As I’ve covered before, I’m a big fan of Blender and 3D art in general, so why not go the whole hog and do a fully 3D wedding app?

It was actually amazingly easy to do given how good it looks, here I used Unity to create this simple app, and the thing just bloody ran on my phone with very little tinkering indeed. Impressive!

In Unity I placed the objects in an empty scene, and manually blurred a 360-degree background image. Unity supports depth-of-field effects, but this tanked performance and worked intermittently on my phone, so I made do.

I drew the rotating icosahedron, grassy floor, flowers, taxi sign, and text, and the rest came from Sketchfab artists with permissive licenses (thanks guys!).

It’s possible to import animations made in Blender, which has an incredibly good interface for doing so, but for the simple motion I wanted I just hard coded it, e.g.:

using UnityEngine;

// Don't judge me too hard
public class HelpBox : MonoBehaviour
{
    float t = 0f;
    float rotY = 0.03f;
    float startY = -4.61f;
    float ampY = 0.2f;

    void Start() {}

    // Update is called once per frame
    void Update() {
        t += 0.01f;
        rotY += 0.06f;
        float newY = startY + ampY * Mathf.Sin(t);
        transform.position = new Vector3(transform.position.x, newY, transform.position.z);
        transform.rotation = Quaternion.Euler(
            transform.rotation.eulerAngles.x,
            rotY,
            transform.rotation.eulerAngles.z
        );
    }
}

You’ll notice that this class implements an Update() method. All Unity objects update their state once per frame, when their Update() methods are called. In my day job I often work with React, which is a declarative library for managing UI state where the gory details of actually updating the things on the screen is abstracted away from you. Working at a level slightly closer to what is actually happening was a bit tricky sometimes, managing the various combinations of states parts of the UI could be in. I’m sure anyone who has spent more than a few weeks dabbling with immediate-mode GUIs (as these are known) will chime in shortly with some best-practices.

Clicking on the various objects flew the camera towards the object (disabling touch interactions while it did) and opened a UI panel, e.g:

The Unity UI system has a few rough edges, but it was surprisingly responsive to different screen sizes. Additionally, because everything is running inside a game engine, you can apply fancy shader effects to any UI surface, as in the blur effect above.

In addition to the ‘usual’ boring parts of a wedding app, namely schedules, driving directions, website addresses etc., I added a couple of fun extra features…

Automatic wedding advice

As part of our user onboarding flow, err, I mean our RSVP process, we asked our guests for a sage piece of wedding advice. At previous weddings I’ve been to, this advice has been made into an artful collage, or inserted into custom fortune cookies.

These are nice ideas, but I wanted something really useful for our guests to take home with them. Through the app they therefore gained access to a generative bigram language model trained on their collective wisdom:

Profound.

This is an unnecessarily fancy way of saying I generated a Markov chain – e.g. in python:

words = [get_random_word()]

while True:
    last_word = words[len(words) - 1]
    next_word = get_random_next_word(last_word)
    if next_word == 'END':
        break
    words.append(next_word)

advice = ' '.join(words)

The probabilities required for get_random_word() and get_random_next_word() were encoded in the app, and then sentences are generated when clicking the button.

Secret codes

A second fun thing was to incorporate the real world into the app. Clicking on the camera opened a live camera viewfinder (actually a live image preview applied as the texture to a flat 2D plane):

Whoa, meta

When a special QR code was recognised, a fun baby photo was displayed.

When all of the codes were scanned, a special part of the app was unlocked which allowed the user to upload their scores to a minimal web server I wrote in Flask, saving scores to mongoDB. Unfortunately no one managed to find all of the codes, rendering this part somewhat useless.

Actually doing the recognition was again very simple using a library called ZXing:

using ZXing;

public class QRImage : MonoBehaviour {
    public WebCamTexture webCam = null;
    public Texture2D jasonImage;
    // other images...

    void Start() {
        mCamera = new WebCamTexture();
    }

    void Update() {
        IBarcodeReader barcodeReader = new BarcodeReader();
        var result = barcodeReader.Decode(webCam.GetPixels32(), mCamera.width, mCamera.height);
    }
}

Amazingly, downloading a single DLL and putting it in a folder allowed me to recognise barcodes on Windows, macOS, and Android. I’m not sure if this ease-of-use is Unity-specific, but it was pretty great.

Another feature which I thought was pretty cool was the way public class properties are exposed in the Unity editor UI. In the above I hard-coded the various images which could appear, which then magically appeared in the editor when selecting the UI object representing the viewfinder:

And with human-friendly names too!

From here it is possible to define properties on instances of a class interactively, with a menu or by dragging-and-dropping.

To make the physical QR codes I generated some SVGs representing encoded text strings, which I imported to Blender and then into the Unity editor. The advantage here was that I could light and position the codes in the same way as the rest of the app, adding a bit of a link between the app and the real world.

In Blender…
… and Unity

Finally I printed them out and stuck them in minimal photo frames, then had them hidden around the venue:

Unfortunately they were too well hidden, as not all of them were found, and I forgot to pick them up the next day. Hopefully some future wedding uncovers them and they provoke a bit of a mystery!


I had a great time getting married. Making this app was a very small, but personally fulfilling, part of a wonderful day. Please do let me know in the comments if it inspires any further geekiness down the line!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s