Rune wayS Development Blog #002

Hello! And welcome to another dev log!

Last week was a crazy busy week with a lot of odds and ends started, in progress or completed.

I’ve been finishing up courses for my teaching day job for this quartile, preparing courses for next quartile, completing the first and easiest Unity Certified Associate Certification (don’t ask me why), starting on the Unity User Programmer Certification, updating this website with a new theme & structure, fixing this website’s blog, moving the rune-ways.com developer log over here for the time being, doing some more probuilder tutorials, working a little bit on marketing while getting Unity Collaborate and Cloud Build up and running, thinking on intermediate deliverables I could release to cut up the long haul, working on completing my first dutch Unity course so that I can finally release it, updating my twitter and instagram account, testing out creating Android and iOs builds on windows (and mac) and getting Unity remote to work on android and mac.

I think that was about it. Ah yeah also worked on fixing the lighting setup in my towers of hanoi game, which I apparently made uglier with every release. Still not done (but I did add it as a work in progress to the games section of this website, check it out!).

Although having so many small and bigger tasks intermingled is slightly chaotic and it is always a challenge to balance work/hobby/family time, for the most part evertything went fine. Even had time for some walks, motorcycle trips while the weather is AWeSomE and the odd game of warcraft 1 and farcry 5.

I do notice my sleep schedule shifting in the wrong direction during this whole Corona-lockdown-stay-at-home-thing, which is probably recognizable for a lot of other people too. I get up 15 minutes later every day ;).

ANYWAY.

The thing I worked on most this week was: trying to find out how to create an iPhone build for testing on Windows. Why windows? Because I hate working on a Mac.
I hate the end conclusion even more: you are better off building your iphone app with a Mac. Creating iPhone builds on windows using Cloud Build is …. meh.

So before I’ll go into how to do it in one of my other blog posts, the long and short is that in the end I was able to create iPhone builds on Windows and install them on my phone, and that the resulting workflow is pretty painless and smooth, BUT the fact that it takes around 30 minutes for an empty project killed it for me.
EVERY time you change something => 30 minutes of your life: poof. Gone.
Verified this with Unity: “Yeaap, 30 minutes sounds about right!”.

After moving the whole thing over to my mac, it takes about 1 minute to build and test.
Yay mac I love you (just kidding, I still hate you).

Summing up that means:

  • if you have a fast Android device, use that for testing, the iOs/Apple process sucks balls compared to Android
  • if you have to do iOs and you have a Mac, use it
  • if you have to do iOs and you don’t have a Mac, do it on Windows using Collaborate/Cloud Build, but don’t forget to shift your deadline by another year or so.

More details on the build process and some of the other stuff soon as well!

Rune wayS Development Blog #001

Rune ways development blog #001 ! Yeah! w00t! So…. anyway, where to start? At the beginning probably…

I’ve been wanting to make a game like this, or at least work on a game like this for a long time, but never got to actually doing it. Recent events however, which I might get into some other time, made me bite the bullet and finally start.

In the first phases that always means a lot of turmoil. There is tons of ideas that you have to write down in one format or another, there is a multitude of things you have to research before you even come close to the simplest version of what it is that you have in mind, and even though it is ‘just’ a hobby project, there is also some trepidation on how this will combine with my normal day job and family.

But as the old saying goes, ‘How do you eat an elephant?’. One bite at a time.

No matter how everything goes, I’m excited to work on it, having a lot of fun doing it, learning a lot of new things and enjoying the prospect of discussing, testing and playing it with my friends (and who knows who else)! If all else fails, there is at least that, but the plan of course is to actually finish it, so more on that in another post.

This past week I wrote down some initial game design ideas, created some concept art for a logo (as my son put it: I’m glad to see you are working on the non important elements such as the game name and logo first ;)), did a bunch of probuilder research, restructured & cleaned my website, setup my twitter & instagram account, made some initial room prototypes to figure out the layout, scaling and have something to build on top off and started looking into deploying to android (which was easy) and deploying to iOs from windows (which is !@#^^$&%#@$@@ so far).

Up next is rewriting the design ideas into user stories, blogging some more on my game ideas, and continuing research on mobile deployment, AR and networking. In the meantime I am also thinking about marketing and some intermediate products (aka simpler versions of or completely different but small games) to test/demonstrate some of the things I’ve learned. And sometimes progress is just agonizingly slow with only 2.5 hours per day, especially when the task at hand is complicated and requires 2 days of undivided attention.

Anyway, baby steps! Here is also a little video of the stuff I did this week:

Controlling content visibility through VuMark IDs

Vuforia is a market leading AR platform with SDKs available for iOs, Android and Unity, and even comes integrated with the latter as of Unity version 2017.2. Vuforia offers different marker types, one of which being the VuMark marker type, which allow you to generate seemingly identical marker images that have a unique ID embedded in them. Using this embedded ID you can for example decide what sort of content to display on the VuMark as it is being recognized by the Vuforia tracking system (see the image below). This post explains how (assuming you are using string IDs).

The image above shows one of the VuMarks provided by Vuforia as part of their VuMark-Designer plugin. Note how all the 4 images look similar, but that on a closer look, only the ones in the left column are exact equals, as are the ones in the right column.

As we hold this image up in front of the camera, Vuforia is able to detect 4 instances of the same VuMark (also called a VuMark template), and read the IDs embedded in the images, ending up with 4 images and unique ID count of 2. In the image on the right, we can see how we can control what is being displayed on top of these markers based on their embedded IDs.

Note that this post is not about how to get Vuforia up and running within Unity, or on how to generate a VuMark. It assumes you are already familiar with the basic of AR, Vuforia, VuMarks and VuMark generation, if not see the resources linked below. Also it is not about whether VuMarks are the right choice for you, since VuMarks are more complicated to generate than simple image markers, make sure that VuMarks are right for your specific situation.

That said, let’s have a look at how we can control what is visible on a VuMark through its embedded (string) ID. Vuforia uses a very ingenious system when it comes to VuMarks of which the basic principle is this:

  1.  To use a VuMark, you first have to create a VuMark template using Adobe Illustrator and the plugin provided by Vuforia.
    It is called a template, because many ‘instances’ of the template can be generated, each with their own unique ID.
  2. After finishing the template, you import it into the target manager, specifying the type and length of your ID, so that you can create a downloadable unity package for your application (aka target ‘database’) AND generate instances of your template for download and print. Note however that the downloadable unity package contains enough info to recognize any pattern that can be encoded using your template, whether you actually generate, download and print it or not.
  3. After importing this unity package, you create a VuMark GameObject in your scene through the GameObject/Vuforia/VuMark menu, and navigating to the VuMarkBehaviour script on this object, select the correct database AND the VuMark template. Note that you cannot specify an ID or whatever for this instance, it will match all possible images that can be generated from your chosen template. Because you cannot specify an ID, you can also NOT have multiple copies of the same VuMark template in your scene, because Unity wouldn’t know which one to pick. Any duplicates will award you with some warnings in your console.
  4. Upon recognizing a VuMark in front of the camera, Unity/Vuforia will display any content that you attached to your marker in the editor on top of the marker image in your video feed, and as such it seems nothing is different yet from using a standard image marker for example. However…
  5. … when and only when Vuforia at runtime detects multiple instances of your VuMark template being held up in front of the camera, it will clone your VuMark gameobject with all its content and display the cloned content on the respective marker. Removing the marker image from the feed, will not remove the clones, it will merely deactivate them.

That is it for the basic process, but where and how do these aforementioned IDs come into play?
And how can we control what is displayed on an instance of a VuMark based on its ID?

As said the first thing that happens when you move a marker image in front of the camera is that Vuforia recognizes it and starts tracking it. Using event handlers we can register ourselves to be notified when this happens:


	private void Awake()
	{
		TrackerManager.Instance.
			GetStateManager().
			GetVuMarkManager().
			RegisterVuMarkBehaviourDetectedCallback(onVuMarkBehaviourFound);
	}

The second thing that happens is that Vuforia actually reads the ID encoded in the VuMark, wraps this in a so-called VuMarkTarget and assigns it to the VuMarkBehaviour in question. We can register for that event as well, however to make sure we do not register ourselves for these target-assigned-callbacks multiple times, we should keep a list of VuMarkBehaviour that were found previously:

List<VuMarkBehaviour> registeredBehaviours = new List<VuMarkBehaviour>();

private void onVuMarkBehaviourFound(VuMarkBehaviour pVuMarkBehaviour)
{
    //check if we have already registered for the target assigned callbacks
    if (registeredBehaviours.Contains(pVuMarkBehaviour))
    {
        log("Previously tracked VumarkBehaviour found (" + pVuMarkBehaviour.name+")");
    } else
    {
        log("Newly tracked VumarkBehaviour found (" + pVuMarkBehaviour.name + ")");
        log("Registering for VuMarkTargetAssignedCallbacks from " + pVuMarkBehaviour.name);
 
        //if we hadn't registered yet, we do so now
        registeredBehaviours.Add(pVuMarkBehaviour);
 
        pVuMarkBehaviour.RegisterVuMarkTargetAssignedCallback(
            () => vumarkTargetAssigned(pVuMarkBehaviour)
        );
    }
}

Last but not least, as this target-assigned-callback is being triggered, we now have a) a reference to the VuMarkBehaviour (and thus its GameObject) in question, and a reference to its assigned VuMarkTarget aka its ID. Using this information we can setup a system where we add multiple children to the VuMark in the editor, and selectively enable or disable them based on the ID that we received through the callback. The easiest approach here is to map the IDs to the names of the VuMark’s child game objects:

	/**
	 * Every time a vumarkTarget is assigned to a specific vuMarkBehaviour
	 * we can process it's children to make sure only the right ones are visible.
	 */
	private void vumarkTargetAssigned(VuMarkBehaviour pVuMarkBehaviour)
	{
		log("VuMarkTarget assigned to " + pVuMarkBehaviour.name + " with ID:"+pVuMarkBehaviour.VuMarkTarget.InstanceId.ToString());
	
		string myID = GetID(pVuMarkBehaviour.VuMarkTarget.InstanceId);

		log("Enabling object with ID:" + myID + " ....");

		foreach (Transform child in pVuMarkBehaviour.transform)
		{
			log("Matching gameObject " + child.name + " with ID " + myID + " SetActive (" + (myID == child.name) + ")");
			child.gameObject.SetActive(myID == child.name);
		}
	}

Note that Vuforia fills out any ID strings with string terminator characters if you do not provide enough info, so you might want to use some sort of getID method to sanitize the IDs:

public int IDLength = 2;

/**
 * Helper method to sanitize the returned ID's
 */
private string GetID (InstanceId pInstanceId)
{
	int inputLength = pInstanceId.StringValue.Length;
	int outputLength = Mathf.Min(IDLength, inputLength);
	string subString = pInstanceId.StringValue.Substring(0, outputLength);
	return subString;
}

And to turn the logging on/off we include our own conditional log method:

	[Conditional("VUMARKHANDLER_DEBUG")]
	private void log (string pInfo)
	{
		UnityEngine.Debug.Log("VUMARKHANDLER:"+pInfo);
	}

To use the script above, create an empty GameObject in your scene next to your VuMark, drag the VuMarkHandler script on it, and rename the GameObject appropriately (ILoveCoding? VuMarkHandler? IDSRules? :)) and inform the script of the length of your IDs (note: not the amount of IDs but the length. This also implies all your IDs should have the same length).

Alternatively for a more detailed example of how this works please download this sample project: VuMarkHandlerDemo (210 downloads) , and print these default markers from Vuforia.
Once downloaded and opened, don’t forget to fill in your App License Key in the VuforiaConfiguration.
Run the project, hold up the printed markers in front of the camera and see the script in action.

That’s it!

One final note before ending this post, let’s take a short moment to discuss some implications of not using unique IDs.

Imagine this scenario:

  • we hold up two identical images up in front of the camera, one Image A in our left hand and one Image A in our right hand.
  • as explained above Vuforia will clone your VuMark instance and display the marker’s content once for each instance in front of the camera, which of course is then also identical.
  • now let’s say, you are doing something with this content based on some (random?) condition, for example changing its state, the way an animation plays, the speed of an animation, the color of a model. So we get for example a blue model X on Image A in our left hand and a green model X on the other Image A in our right hand.
  • now you move the images out of the camera’s view frustum and then back in again. All Vuforia sees is two instances of the same template with the same ID again. There is nothing there to control that the blue model X ends up on Image A in your left hand again and green on the other, they could as well be swapped. That is only possible when you do use unique IDs. Of course this all makes sense and is very logical, but still it is something I think you should be aware of.