Common WWW

Unity’s WWW class is quite powerful. Give it a URL and it will download that file in the background. Provide it with some form data and it will encode it properly and post it for you. It can even load files from inside your APK on Android.

As powerful as the WWW class is, there is really only one way to use it, in a coroutine. Start the download, yield until it finishes, and finally process the error or payload. I found that nearly all times I used the WWW class the coroutine followed this pattern. So instead of rewriting it again, I made a library of the pattern.

I present the WWWNetworking library. It implements the most common WWW use patterns so you can use callbacks instead of implementing coroutines. You can also queue up multiple downloads and control the amount of concurrent downloads. It even provides singleton access to a default instance.

using UnityEngine;
using WWWNetworking;
public class FloatingImage : MonoBehaviour {
  void Start() {
    NetworkingEngineSingleton.Instance.Download("http://images.earthcam.com/ec_metros/ourcams/fridays.jpg", www => {
      GetComponent<Renderer>().material.mainTexture = www.texture;
    });
  }
}

The core of the library is the NetworkingEngine component. It is essentially a queue of tasks to run. When there are fewer than the maximum amount of allowed concurrent tasks running it starts one from the queue. The maximum is user configurable so you can dynamically change the amount of resources to consume. There is also a singleton-like default instance available for when you don’t want to deal with adding components. The example above shows the singleton-like default instance.

Unity iOS Plugin Basics

One of my favorite things about Unity is how easy it is to port games to multiple platforms. The simplest of games require no work to target a new platform. Literally none. This makes developing in Unity a time saver because there are very small porting costs.

However keeping the game purely within the engine comes with drawbacks. Primarily, little system integration. Many platforms have features outside of the game which you might want to take advantage of. For instance, iOS has twitter sharing built in to the OS. This is a feature Unity does not implement. So how do we use it? Through the use of plugins.

Plugins allow you to call into code written and potentially compiled outside of Unity. This is extremely powerful because it allows you to do pretty much anything the platform you’re targeting can do. Going back to the iOS twitter example, you can call into the native Cocoa Touch APIs.

Let’s try this out by writing a simple plugin to show a dialog to post to twitter. This API is built into iOS versions 5 and newer. I will be assuming you are targeting at least that version. If you are targeting something older you will need to include checks for the iOS version before calling the API. We need two functions. The first will check whether we can post to twitter. The second to do the posting. The social sharing API is documented at https://developer.apple.com/library/ios/documentation/NetworkingInternet/Reference/SLComposeViewController_Class/Reference/Reference.html. It will come in handy.


The mono runtime makes calls into native code using C standards. Any language that follows the C calling convention can be called. Unfortunately Objective-C does not follow this convention. We will have to wrap Objective-C APIs with C code to make it available to Unity. this is done by putting our calls inside C functions and using a C compiler to compile it. Our file will contain calls into C++ so we need to use a .mm file with Extern "C" { at the top and } at the bottom to avoid name mangling issues.

// Check if c++ compiler
#if __cplusplus
Extern "C" {  // Avoid name mangling issues
#end if

#if __cplusplus
}  // Close Extern C
#endif

Put this file in the Assets/Plugins/iOS/ folder in your project. This is a special folder. When you build for iOS, any native libraries or code in this folder are copied to the Xcode project where they are compiled and linked with the rest of Unity.

Now, in Unity create a new C♯ file. This file will act as the Unity side to the plugin.

// Notice it doesn't extend MonoBehaviour
public class TwitterSharing
{
}

Let’s start by adding a simple call to find out if Twitter is available. SLComposeViewController contains a class method called isAvailableForServiceType to check the availability of a given service. The constant for Twitter is SLServiceTypeTwitter.

// In Social.framework, imports social sharing classes and constants
#import <Social/Social.h>

#if __cplusplus
Extern "C" {
#end if

bool _isTwitterAvailable()
{
    // Returns true when Twitter is available
    return [SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter];
}

#if __cplusplus
}
#endif

When calling native code, mono “marshals” the parameters and return values. Basically it copies stuff. This is needed because C and C♯ have different memory management. Primitive types, integer, floating point, and boolean, are automatically converted to and from their respective types. Because of this we can use a bool in C♯ just as we would in C. Strings work a little differently as we will see later.

using System.Runtime.InteropServices;  // For calling into native code

public class TwitterSharing
{
// The plugin is only compiled for the iOS platform, check if Unity is compiling for it.
#if UNITY_IPHONE
    // Specifies which binary file contains the function.
    // For plugins you write the library is always "__Internal".
    [DllImport("__Internal")]
    // Has the same signature as in the C file
    private extern static bool _isTwitterAvailable();
#endif

    public bool IsTwitterAvailable()
    {
#if UNITY_IPHONE
        // Calls into native code
        return _isTwitterAvailable();
#else
        // The method needs to always return something.
        return false;
#endif
    }
}

Now you can check whether Twitter is available from game code. Debug.Log(TwitterSharing.IsTwitterAvailable()); will print whether twitter is available when running on iOS. But this is no fun. We want to post to Twitter. Let’s add a function to do just that. But first, let’s cover how mono marshals strings from C♯ to C. When you send a string as a parameter mono converts it into a null terminated UTF8 character array (char[] ending with \0) for native code. The sharing service expects an NSString so we have to convert it using stringWithUTF8String.

#import <Social/Social.h>
// Contains functions to call into Unity
#include "UnityInterface.h"

#if __cplusplus
Extern "C" {
#end if

bool _isTwitterAvailable()
{
    return [SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter];
}

void _postToTwitter(char* text)  // Make note of the signature
{
    // Create a view for Twitter sharing
    SLComposeViewController* shareSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
    // Convert characters into NSString.
    [shareSheet setInitialText:[NSString stringWithUTF8String:text]];
    // Get the Unity native view and tell it to show the twitter view.
    [UnityGetGLViewController() presentViewController:shareSheet animated:YES completion:NULL];
}

#if __cplusplus
}
#endif

Now to make the unity side.

using System.Runtime.InteropServices;

public class TwitterSharing
{
#if UNITY_IPHONE
    [DllImport("__Internal")]
    private extern static bool _isTwitterAvailable();

    // This specifies which binary file contains the function.
    // For plugins you write the library is always "__Internal".
    [DllImport("__Internal")]
    // Notice here we say the parameter is a string
    private extern static void _postToTwitter(string text);
#endif

    public bool IsTwitterAvailable()
    {
#if UNITY_IPHONE
        return _isTwitterAvailable();
#else
        return false;
#endif
    }

    public void PostToTwitter(string text)
    {
#if UNITY_IPHONE
        // Call native function
        _postToTwitter(text);
#endif
    }
}

Now we can do something like the following from within the game.

if (TwitterSharing.IsTwitterAvailable()) {
    TwitterSharing.PostToTwitter("Tweet!");
}

This will bring up a twitter share dialog for the user to tweet with the text “Tweet!” already filled in. Some things to go over in the future include performing an action when the player successfully tweets and attaching a screenshot/image.

More information is available at http://www.mono-project.com/Interop_with_Native_Libraries.

Unity Property Drawer Attributes

The Unity editor is a really useful tool when making a game. A lot of its power comes from how customizable it is. If you want to make a new window to do some custom action it is as easy as writing code like you would for the game. Custom inspectors and property drawers are the most common form of customization. These work in the inspector to simplify working with your components.

There are preexisting property drawer attributes you can use to simplify your inspector. Recently, I wanted to find if there was one I could use for a script I was working on. Unfortunately there wasn’t a comprehensive list of attributes built in to Unity. So I went ahead and made a list for future reference.


Range

Since 4.0
This changes a float or int to a slider. The parameters are the lowest and highest allowed values.
Range

[Range(0, 100.5f)]
public float range;
[Range(0, 5)]
public int moreRange;
[Range(0, 10)]
public float[] rangeArray;

Multiline

Since 4.0
Changes a string to use multiple lines in the input field. The optional parameter is the number of lines.
Multiline

[Multiline]
public string multiline;
[Multiline(6)]
public string moreMultiline;
[Multiline]
public string[] multilineArray;

Textarea

Since 4.5
Changes a string to a multiple line text area with scroll bars when the text doesn’t fit.
TextArea

[TextArea]
public string textArea;
[TextArea(3, 6)]
public string moreTextArea;
[TextArea]
public string[] textAreaArray;

There are other attributes which do not alter behavior or appearance I will likely go over later.

Unity Android Plugin Environment

I’ve recently begun work on android platform integrations into Crowman & Wolfboy. We’ve had a playable build of the game on Android for a while now, but some parts need more integration than others. I ended up having to write a java library for inclusion in the project.

This posed a new problem for us. All our iOS native plugins were included as objective-c files. Unity then copied those source files into the compiled project for XCode to build. This made it easy to include the source files in version control while keeping the build process simple. Android plugins aren’t so simple.

Unity requires android plugins be precompiled JAR files. I think it has something to do with Unity’s build process for android apps, but that doesn’t really matter. Those JAR files must be in the ‘Special Folder’ at the path Assets/Plugins/Android/. I wanted a way to easily keep the java source files in the same repository as the main project, but also keep the build process for the plugin simple.

The first thing I tried was putting the whole Eclipse workspace under versio control. That didn’t work because a lot of paths are saved as part of the workspace. The JDK path is different for different developers. The Android SDK path is different too.

I ended up making an Eclipse workspace adjacent to the main project folder. This workspace contained java projects as usual. Those java projects then used linked source folders. The source files were in a sub folder of the special android plugin folder. Each eclipse project then linked to its specific source folder. Then I can export the JAR to an external location (that being the special android plugin folder).

This setup will requires each developer configure their own eclipse workspace. Other than that the build process for a change to java code is easy as an export in Eclipse followed by a build in the Unity Editor. Not quite the ideal one-click-build, but java code shouldn’t be changed very often anyway.

XKCD Colors

I was working on a post about integrating the TestFlight SDK into Unity, but since it is no more I’ll have to skip that topic.

Instead let me introduce, XKCD Colors as less mixins.

I am an avid reader of the XKCD comics. If you haven’t read it take a minute right now to go read some. It is a staple of internet culture.

Well, a little while ago Randall held a survey about color names. The survey showed a color on screen and asked the user to name it. The names for each hex code were compiled into a list. I converted the list into LESS mixins to make them more useful. You are free to download and us the file yourself.

Some color names contained characters not allowed in CSS. I converted spaces to dash (‘ ‘ to ‘-‘) slashes to double dashes (‘/’ to ‘–‘) and removed apostrophes. I also prefixed each color name with “xkcd-” to prevent conflicts. In total there are 949 colors.

Here’s a sample.

@xkcd-fern-green: #548d44;
@xkcd-bright-lilac: #c95efb;
@xkcd-weird-green: #3ae57f;
@xkcd-peacock-blue: #016795;
@xkcd-avocado-green: #87a922;
@xkcd-faded-orange: #f0944d;
@xkcd-grape-purple: #5d1451;
@xkcd-hot-green: #25ff29;
@xkcd-lime-yellow: #d0fe1d;
@xkcd-mango: #ffa62b;

More AppleScript

After my last post I really wanted to explore AppleScript some more. So that’s what I did.

One thing I like to do is listen to podcast episodes in chronological order. That is to say episodes from different podcasts. But also one episode at a time. The podcasts I subscribe to average about 50 minutes per episode. I use these as a measure of time while working. When an episode finishes I know it is time to take a quick break, get up, walk around for a minute it two. I don’t want the default iTunes behavior of going straight into the next episode and have to pause it when I get up. Some people might say that there is a particular program which can already do this easily. I didn’t really feel like getting a new program to do it since I was already managing them in iTunes. And I wanted something to do in AppleScript. It seemed like a good candidate.

I wrote this script for iTunes 10. There are problems with it in iTunes 11 because iTunes appears to sometimes discard “played” state of individual episodes. Anyway, here it is.

tell application "iTunes"
	set podcastsPlaylist to some playlist whose special kind is Podcasts
	set allUnplayedPodcastEpisodes to tracks in podcastsPlaylist whose unplayed is true
	if (length of allUnplayedPodcastEpisodes) is 1 then
		play first item in allUnplayedPodcastEpisodes
	else if (length of allUnplayedPodcastEpisodes) is greater than 1 then
		set oldestPodcastEpisode to first item in allUnplayedPodcastEpisodes
		repeat with i from 2 to length of allUnplayedPodcastEpisodes
			set podcastEpisode to item i in allUnplayedPodcastEpisodes
			if release date of podcastEpisode comes before release date of oldestPodcastEpisode then
				set oldestPodcastEpisode to podcastEpisode
			end if
		end repeat
		play oldestPodcastEpisode
	end if
end tell

My first post about AppleScript didn’t describe what the code does. Let’s do better with this post. People with little to no programming experience should still be able to understand it.


The first line, tell application "iTunes", means to use the iTunes dictionary for subsequent lines. An AppleScript dictionary contains information about commands and types specific to a particular application.

Line two, set podcastsPlaylist to some playlist whose special kind is Podcasts, may look a little strange to those unfamiliar with AppleScript, but familiar with other languages. The expression some playlist whose special kind is Podcasts searches all instances of the type playlist and returns the first one it finds with special kind of Podcasts. It turns out the only playlist with special kind of Podcasts is the official podcast playlist containing all episodes. The result is then set to the variable podcastsPlaylist.

The third line, set allUnplayedPodcastEpisodes to tracks in podcastsPlaylist whose unplayed is true, similarly takes care of many details for you. The expression tracks in podcastsPlaylist whose unplayed is true finds and returns all unplayed episodes in the variable podcastsPlaylist. (This is actually where the script trips up. iTunes appears to not save the unplayed value properly, and podcast episodes which I previously played appear unplayed.) The resulting list of that expression is then set to the variable allUnplayedPodcastEpisodes.

The next line, if (length of allUnplayedPodcastEpisodes) is 1 then, is an optimization. Most of the work of the script is in searching for the oldest episode. When there is only one unplayed episode it is automatically the oldest. This line checks for that condition. When there is only one episode, the next line, play first item in allUnplayedPodcastEpisodes, executes. The variable allUnplayedPodcastEpisodes is a list, meaning there are multiple elements. List elements are normally accessed by index with index 0 being the first element, index 1 being the second, and so on. AppleScript has some shortcuts, one of which is accessing the first element. The line sends the play command with that first element. The play command accepts a media object for iTunes to begin playing. The iTunes dictionary defines it, so it only works after a tell application "iTunes" command.

The next line, else if (length of allUnplayedPodcastEpisodes) is greater than 1 then, checks to make sure there are podcast episodes. If there aren’t any episodes there is no point to running any more code because in the end it wouldn’t do anything. The condition checks for more than one because it is clearer under what conditions the following code runs.

Now we’ve come to the interesting part. This is where we search for the oldest episode. Since the date of the oldest episode is unknown we must check every episode looking for the earliest date. A basic linear search is good for this. It goes through the list comparing each episode to the oldest known episode.

The line set oldestPodcastEpisode to first item in allUnplayedPodcastEpisodes starts the algorithm. When first starting there is no “oldest episode” so one needs picked. We use the first element in the list because it is easy to access.

The following line, repeat with i from 2 to length of allUnplayedPodcastEpisodes, is the loop of what to look at. It tells the AppleScript interpreter to run the lines after it and before its corresponding end repeat multiple times. The portion with i says to use the variable i to store a different value each iteration. The rest of the line, from 2 to length of allUnplayedPodcastEpisode, says i will start as 2 and end as the number of elements in allUnplayedPodcastEpisode. Since it doesn’t define an increment, the value will increase by 1 each iteration. The first time an iteration runs i will be 2, the second time it will be 3, and so on until it equals the number of elements in allUnplayedPodcastEpisode. The first line within the loop, set podcastEpisode to item i in allUnplayedPodcastEpisodes stores the episode the loop is examining into a variable to make it easy to refer to later. It really just makes the code more readable. Instead of having item i in allUnplayedPodcastEpisodes every time we want to access the episode, we use the podcastEpisode variable.

The second line of the loop, if release date of podcastEpisode comes before release date of oldestPodcastEpisode then finds the older episode. It compares the release date of the currently known oldest episode to the episode of the loop iteration. When the release date of the iteration’s episode is before the oldest date the line inside the then block, set oldestPodcastEpisode to podcastEpisode, saves the iteration’s episodes as the oldest.

Once all elements of allUnplayedPodcastEpisodes have been examined, the script has saved the oldest episode in the oldestPodcastEpisode variable. At that point, we tell iTunes to play it by sending the play command.


That’s all. I covered a lot of the basics of AppleScript. Feel free to ask any questions in the comments.

AppleScript to the Rescue

Screenshot

Screenshot of NetNewsWire AppleScript documentation

As a long time user of Google reader, it saddens me to see the service closed. A ton of information will be lost. All the starred articles and feeds no longer available will disappear into the ether.

I started looking into alternatives shortly after hearing about the intended closure. One reader I had heard a lot about in the past was NetNewsWire. One thing stuck out to me was the lack of sharing options. It has options to re-blog, save to Delicious, and send to Instapaper. There weren’t even options to share on Facebook or Twitter. I was particularly disappointed by no ability to save to Evernote. Evernote has greater persistence and searchability than other services. When adding an article to Evernote, the content syncs to all desktop clients. In the unlikely event Evernote shuts down, all the data in my Evernote maintains on my desktop.

Not to worry, AppleScript to the rescue. Both NetNewsWire and Evernote have AppleScript interfaces allowing automation of simple tasks. This script copies the current article in NetNewsWire into Evernote. Here is the code.

-- Get info about headline
tell application "NetNewsWire"
    set headlineTitle to title of selectedHeadline
    set headlineURL to URL of selectedHeadline
    set headlineDescription to description of selectedHeadline
    set headlinePublished to date published of selectedHeadline
end tell

-- Send it to Evernote
tell application "Evernote"
    set newNote to create note with html headlineDescription
    set title of newNote to headlineTitle
    set source URL of newNote to headlineURL
    set subject date of newNote to headlinePublished
end tell

Pretty straightforward. Also, Evernote must be open and logged in for the script to work.

A diary on working with third party code

There comes a time for every developer when they must work with code written by somebody else. Some times it’s voluntary. Say for instance there is a useful library the developer wants to use instead of writing all the code themselves. Other times, it’s not. Like when a new developer joins a project already in progress. The example in this post is of the former.

I was recently working with a Unity plugin which enables easy development of 2D environments. Given that Unity is a 3D engine having a framework for 2D scenes is useful and speeds development. The team unanimously decided to use an existing plugin instead of building one in-house. We immediately started building the game around this framework. However we did have to pay a small fee.

A couple of days later came a surprise. The developer of the library released a major update. Version 2.0! Given that we had purchased the library less than a week before, we tried contacting the developer to find out if we could get the upgrade for free. We were a little concerned with the response, or lack thereof. We didn’t receive any response at all. Not a yes, not a no, nothing. Not a big deal, we still had version one to use.

Fast forward a few weeks, and then comes an issue. It turns out there was a bug in the library affecting sprites inside a scaled parent. I was able to fix the bug, but only by introducing another issue. Any sprite not in another object moved. I then found out the new version of the plugin fixes the bug among other new features. However, since we had not heard back from the developers it would be a paid upgrade for us.

In the end we bought version 2 of the library only to find out it introduced the same issue my fix did.

Anyway, there is no real lesson to learn from all this. It’s just one of the many issues we dealt with during development.

Switching Engines

When I started work on Crowman & Wolfboy there had already been some development complete on the game. A few levels were already built and saving and loading were being coded. However we soon ran into several problems with development.

Documentation seemed really out-of-date with the original engine. Code wasn’t working as the documentation specified it should. Even the examples given didn’t work. It was a serious problem which made progress slow.

Not long after joining we started looking into alternatives. First, we came up with a list of requirements which an alternate need to meet to even be considered. With nearly all the art complete, the new engine needed to support 2D art assets. Nearly all engines are capable of this. A strictly 2D engine is the obvious answer, but 3D engines can be clamped into 2D so we didn’t want to rule them out. We wanted to target both iPhone and Android mobile platforms so solutions specific to one platform were quickly excluded. For example, when we were doing this Cocos2D only supported iOS and would require another separate engine for development on Android. Next, documentation needed to be current. This was the original problem we were trying to get away from.

From this list of requirements we narrowed the possibilities and eventually chose Unity. It is a 3D engine but has several frameworks for building 2D games. It supports exporting to both iOS and Android platforms. And lastly, documentation is excellent. As an added bonus, there is an active community using Unity.

Since switching we haven’t looked back.

The Importance of Documentation

In the previous post I describe several forms of documentation and their uses. Hopefully it’s clear that each form is important and serves a distinct purpose. In a typical day, I find myself referencing at least two of these forms. some days I don’t reference any documentation. On days I do, it is most often a function list and forum.

For example, I might start off the day needing to do some complex operation with an object’s rotation in Unity. You can see Unity’s class list with the rest of their scripting documentation. I know an object’s rotation is represented by a quaternion so let’s start there. Now I see that the operation is already implemented as part of the class requiring only one line o code on my part. Later on, when it’s not working the way I expect, I can heard either their forum or Q/A site. Now I can search for other people with the same problem or ask a new question myself. An answer will probably send me back to the class list as a reference.

These are the kinds of connections present between all the forms of documentation. Each one serves a specific purpose and knowing that purpose will help you find information faster.