Coroutines in Unity – Encapsulating with Promises [Part 3]

Facebooktwittergoogle_plusredditpinterestlinkedinmail

 

In the last part of the series we’re going to build a real example of a REST API Interface using Unity’s Coroutines as an internal web requests tool and Promises as an encapsulation layer. We’re going to use the fake REST API service available for everyone to test their services on. It’s a simple API that implements the classic user to-do lists, posts & comments section as well as the album & photos scenario. Very useful if you’re building your own front-end but don’t have your own running server just yet.

NOTE: This tutorial is a bit more advanced and it won’t teach you REST backend theory or JSON serialization. It also assumes you’re already familiar with the RSG Promises we’ve covered in Part 2.

The project

Our project is going to be based around the user to-do lists. The main feature is simple: it’ll take a username as input and provide a list of tasks associated with that user. The application is going to get a list of all the users, find the searched username in it and if that user exists it will then grab all the tasks. Ideally you’d want the user searching to be done server-side, but for the sake of this example let’s say someone hadn’t thought it through and left you to do your job.

For JSON deserialization we’re using the popular JSON .NET framework. If your project is going to be cross-platform you should take a look at JSON.NET for Unity, which uses the same namespace and structure so it can easily be used as a drop-in replacement.

We’re going to work with Unity 5.4.0f3. You can download the .unitypackage here with a complete project and all the necessary plugins. Let’s dive into it.

The project features a Plugins directory, Scenes directory with the single example scene as well as Scripts directory, where the whole codebase sits. The code is structured as follows:

devenv_2016-08-24_11-09-12

Let’s start from the top.

The Models

The Models directory is where the data models’ classes are. They’re essentially the classes with properties mapped to JSON object keys. For example our JSON of a single Task object looks like this:

The associated Model class is then being implemented in the following way:

As you can see, JSON .NET allows for an extremely easy mapping using the JsonProperty attribute. Actually, you can skip these entirely if the property name matches the JSON key. Personally I prefer camelCase in my JSONs and PascalCase in my properties. Keep in mind that for AOT platforms you should use JSON .NET for Unity or use regular fields. Refer to the documentation for more information.

The User model is a stripped model as the jsonplaceholder returns a much bigger JSON, but for the purpose of this example we will not implement all the properties.

Promises as a service interface

Let’s say you’re working on a REST API for a month only to find out that management of your company decided to move to Websocket. Or perhaps you’re ahead of your backend department and want to test new features on your own without the need of using a real server. To remedy this it’s a good idea to implement the Factory pattern which let you choose the exact implementation of your service (APIServiceFactory) by encapsulating a common interface for all of them (IAPIService). The interface is using Promises as the abstraction layer so it’s very easy to use.

To search users and list their tasks we only need two functions:

If you’re going to need another API implementation in the future all you have to do is create a new class that will implement these two methods. The instantiation is done via the factory and the provided config (IClientConfig and ClientConfig):

RestAPIService

The REST API implementation uses the Unity’s Coroutines and the UnityWebRequest class under the hood. Because of that, the factory creates a GameObject and attaches the RestAPIService class, which also extends the MonoBehaviour. This lets us encapsulate the coroutines even further – you’ll be able to use the service in all of the classes, because the interface deals with Promises only. For example, getting the user tasks is done like so:

Notice how easily we control the output with promise.Resolve() and promise.Reject().

TestAPIService

The test implementation is just an example of what you can do. It returns objects without any external calls, but you could also use it as a room to test your JSON deserialization without launching a real server. The bottom line is that this should be the space to mess around with no worries that you’re hard-coding some test scenarios which need to be commented out later. All you have to do is change the config to the real service and you’re done.

So for example, if you’d like to test how your tasks` UI look, but don’t have the tasks functionality done server-side just yet, simply implement the test service and the GetUserTasks() method to return a bunch of test objects:

Notice that you can resolve promises instantly when needed.

The result

The payoff is the example test scene and the MainScreenController class which utilizes the interface. First, it initializes the service using the Factory:

As mentioned earlier, changing to Test implementation is as simple as swapping that APIType property in the config. The UI consists of a single input field where you type in the username and a button to get all the user tasks. Using the common interface it couldn’t be any simpler:

2016-08-24_10-46-14

Summary

And at last we come to an end of the series. Again, the final project can be downloaded as the .unitypackage here. In conclusion Promises prove to be a great way to abstract your code from Unity specific Coroutines. They can also be used in many different cases and are an elegant way to create clean interfaces. We hope you’ll enjoy them as much as we do. If you have any questions about the series or the example project, feel free to leave a comment in the section below.

5 thoughts on “Coroutines in Unity – Encapsulating with Promises [Part 3]

  1. You might be interested in checking out my extensive work on this topic…

    Using promises for async operations in Unity:
    http://www.what-could-possibly-go-wrong.com/using-promises-for-unity-async-operations/

    Using promises for game development:
    http://www.what-could-possibly-go-wrong.com/promises-for-game-development/

    And of course Real Serious Games’ C# promise library built for Unity3d:
    https://github.com/Real-Serious-Games/C-Sharp-Promise

  2. Shrikky says:

    I am very impressed by the quality of blogs in this website, I came across this website couple of days back and I quickly went through most of the blog posts in the last few days. I did find a lot of useful posts especially with the Promises/REST and the FSM. I must say that I’ve been pretty much fighting to implement steam leaderboards ( I have 50 leaderboards and I’ve faced many problems due to callbacks/call results and sequential coroutines – I did not have a choice). Eventually it led to a lot of bad coding, delayed UI updates due to callbacks etc. I want to try this on my steam leaderboards implementations.

Leave a Reply

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