Working with Parse.com in Unity 3D – Part 1 – Intro and App Structure

Working with Parse.com in Unity 3D – Part 1 – Intro and App Structure

This is part of a three-post series on working with Parse.com in Unity. For more info please see the other posts in the series:

Part 1 – Intro and App Structure
Part 2 – Services, Helpers and Looming
Part 3 – Tests, Typescript and Common Code

For a while it has been my intention to follow up my work with Parse.com in Unity, but other things have always gotten in the way and thus I have only just managed to get round to it.

Over the past 9 months of working with Parse I have encountered some pretty nasty issues which I decided to solidify by putting together this guide and sample project which I hope will help others out there!

But first..

What is Parse.com?

Parse.com is a backend as a service (BaaS). This means they take care of managing servers, operating systems, load balancing and all of that leaving you with a simple API that you can use to get what you need done.

I have been using Parse for most of my projects of late for a few reasons, mainly its ease of use (more of that later) and incredibly generous pricing:

2014-11-10_15-58-19
(thats about 77 million free API requests per month, per app!)

In comparison to the competition its much cheaper, Microsoft’s Azure based Mobile Services for example:

2014-11-10_16-00-33

Parse.com features a simple way to store..

var shield = new Armor
{
  DisplayName = "Wooden Shield",
  IsFireproof = false,
  Rupees = 50
};

shield.SaveAsync();

.. and retrieve data:

var query = new ParseQuery<Armor>()
    .WhereLessThanOrEqualTo("rupees", ((Player)ParseUser.CurrentUser).Rupees);
query.FindAsync().ContinueWith(t =>
{
    IEnumerable<Armor> result = t.Result;
});

You can also have routines run on the server written using Javascript:

Parse.Cloud.define("averageStars", function(request, response) {
  var query = new Parse.Query("Review");
  query.equalTo("movie", request.params.movie);
  query.find({
    success: function(results) {
      var sum = 0;
      for (var i = 0; i < results.length; ++i) {
        sum += results[i].get("stars");
      }
      response.success(sum / results.length);
    },
    error: function() {
      response.error("movie lookup failed");
    }
  });
});

I wont go into the API any more here but their docs are pretty good and will explain things much better than me: https://www.parse.com/docs/unity_guide

Parse Unity Sample Project

I have provided a simple Sample Project that hopefully should help with explaining how things work:

The source code for which can be found on github here.

Application Structure

Although Parse.com has a Unity SDK that looks very simmilar to the .Net API, there are some pretty important differences which ill get into later.

Firstly, everyone’s project structure is different and only experience and time will lead you to your own personal preference. For me, I like to setup my project folder like this:

2014-11-10_16-15-46

One folder for the Unity project, one for the Backend and one Common library that is shared between the two.

If you use Visual studio this can all be set into one solution:

2014-11-10_16-17-54

Frontend (ParseUnitySampleProject)

This is the Unity project, you can structure this how you like but I have provided a simple login / signup / logged in menus demo to show how I organise the libraries and code within it:

2014-11-10_16-51-47

Common

The common project contains code that is common to the frontend and backend. This is usually just models that represent the database, in this case its just a simple class GameUser:

[ParseClassName("_User")]
public class GameUser : ParseUser
{       
	[ParseFieldName("playerName")]
	public string PlayerName
	{
		get { return GetProperty<string>("PlayerName"); }
		set { SetProperty<string>(value, "PlayerName"); }
	}

	public bool IsPlayerNameSet { get { return !String.IsNullOrEmpty(PlayerName); } }
}

Every time you build the common project the DLL that gets created is automatically copied into the game thanks to the build task:

2014-11-10_16-22-42

Backend

The backend contains the code that will run on Parse.com and the associated tests:

2014-11-10_16-53-18

I like to use Typescript for my Parse.com backend and so the project is a Typescript project mixed with C# for unit testing. I have provided my unfinished Typescript definition file for parse.com with the project:

2014-11-10_16-54-54

To be continued..

In the next part of this post ill talk more about the specifics of how to interact with the Parse.com API in Unity and some special helpers that I have developed to aid with that.

Tinkering with Google Polymer and Typescript

Tinkering with Google Polymer and Typescript

I recently had the opportunity to experiment with something I have been meaning to play with for a little while, Google’s Polymer.

I first heard about Polymer at Google IO 2014:

I highly recommend watching that video if you want to know more about Polymer but the high level idea is that its a library built on top of the new HTML Web Components and it allows us to write our own custom HTML elements in a way that makes sense.

I really liked the look of it as it reminded me greatly of Adobe’s Flex (MXML) in the way you can write your own components in a declarative manner then bind to various data in the code behind.

So it took me a few days to get my head around things to begin with. One thing I would recommend if you are interested in tinkering with Polymer then first checkout this video:

I wish I had used that to begin with as it would have saved me a whole heap of “is this the correct way to do it?” headaches.

One complication with my setup however is that I really wanted to use Typescript rather than raw Javascript for my code. Well fortunately Visual Studio has really great Typescript support and I was able to create a Typescript project in Visual studio and get cracking immediately.

I ran into an issue with how to use Polymer with Typescript however and there wasn’t too much info on the web out there so hopefully this short guide will help:

1) Create your custom element

I’m using a login element as an example:

login.html

<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="/bower_components/paper-toast/paper-toast.html">
<link rel="import" href="/bower_components/paper-button/paper-button.html">
<link rel="import" href="/bower_components/paper-input/paper-input.html">
<link rel="import" href="/bower_components/paper-fab/paper-fab.html">
<link rel="import" href="/bower_components/core-icons/core-icons.html">

<polymer-element name="tt-login" attributes="userService">
    <template>

        <style>

            .card {
                margin-top: 64px;
                max-height: 580px;
                max-width: 512px;
                box-shadow: 0 2px 5px 0 rgba(0,0,0,.26);
                border-radius: 2px;
                padding: 20px 16px;
                box-sizing: border-box;
                background-color: white;
            }
			
        </style>

        <div class="card">
            <h1>Login</h1>


            <paper-input floatinglabel label="Your email" type="email" value="{{email}}" error="Input is not an email!"></paper-input>
            <paper-input floatinglabel label="Your password" type="password" value="{{password}}" error="Input is not an email!"></paper-input>

            
            <div horizontal center layout>
                <a href="/#signup"><paper-button disabled?="{{isLoggingIn}}">Signup</paper-button></a>
                <div flex></div>
                <paper-button id="check" on-click="{{login}}" disabled?="{{isLoggingIn}}">Login</paper-button>
            </div>          

            <paper-toast id="errorToast"></paper-toast>
        </div>        

    </template>
    <script src="login.js"></script>
</polymer-element>

Its a pretty simple login element with some binding using some of Google’s paper elements but hopefully you get the idea.

2) Create your custom element’s script

login.ts

class Login extends PolymerElement {

    userService: UserService;

    email: string;
    password: string;
    isLoggingIn: boolean;

    errorToast: PaperToast;

    ready() {
        this.errorToast = this.$.errorToast;
    }

    login() {
        this.isLoggingIn = true;
        this.userService.login(this.email, this.password)
            .then(user => this.onUserLoggedIn(user))
            .fail(err => this.onParseError(err));
    }

    private onUserLoggedIn(u: Parse.User) {
        this.isLoggingIn = false;
        this.fire("logged-in");
    }

    private onParseError(error: Parse.Error) {
        this.isLoggingIn = false;
        this.errorToast.text = error.message;
        this.errorToast.show();
    }

}

Polymer(Login.prototype);

Here we define the variables that we are going to bind to in the element. We also include the “userService” which is an attribute that is a dependency passed into the element.

Note that im able to use this.$ to access the “errorToast” element by ID. Im able to do this because Login extends a class I wrote called PolymerElement:

class PolymerElement {
    $: any;
    style:any;
    fire(eventname: string, payload?: any) { }
    addEventListener(eventName: string, handler: (e : CustomEvent) => void) { }
} 

For now it a bit of a hack to get around the fact that Typescript requires that you implement all elements in an interface so I cant just do “class Login implements HTMLElement”.

Note also the call to Polymer:

Polymer(Login.prototype);

We must pass the prototype into the call then do our variable initting in the ready() function.

3) Use the element

Now we can use it pretty easily:

<!DOCTYPE html>
<html>
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
    <title>Login Example</title>
        
    <script src="bower_components/platform/platform.js"></script>

    <!-- This is only needed because of the Typescript interface problem! -->
    <script src="lib/polymer_utils.js"></script>

	<!-- Our login element -->
    <link rel="import" href="login.html">

</head>
<body fullbleed layout vertical unresolved>
	<userService id="userService"></userService>
    <login userService="{{$.userService}}"></login>
</body>
</html>

I hope that helps other that are looking to do their own tinkering with Typescript and Polymer!

MK Bridges

MK Bridges

MK Bridges is an ongoing freelance project I worked on for Martin-Kaye Solicitors.

The firm works with a number of suppliers that provide them clients. Those suppliers need information about the progress of a case such as when certain milestones have been met. Unfortunately MK’s current system doesn’t easily allow for this reporting to third parties and thus they were logging into each supplier’s website and manually entering the data whenever the case updated. As this can happen many times a day for each case the extra workload was high.

MK Bridges is a solution to that problem. It uses daily snapshots of the MK database to work out which milestones have been completed and then sends API calls to the relevant supplier thus saving a great deal of manual labour.

It was developed using ASP.NET 5 with Entity Framework 6 with some sprinkling of Typescript for the client side.

screenshot_016 Oct. 06 16.11

Although the project sounds deceptively simple it was actually quite complex and required quite a bit of back and forth with suppliers and hosting providers to link it all up correctly. There is an internal error handling system that uses Mandril to report on errors, a message request and response logging system and a moderately complex system for filtering information to send and display in the user interface.