WinRT API and Unity 5

So I needed access to WinRT APIs in Unity.  (I am only targeting Windows platforms – this will NOT work cross platform.)  Unity docs say you can use WinRT from within Unity (http://docs.unity3d.com/Manual/windowsstore-scripts.html) however the issue I ran into is Unity only supports .NET 2.0 and many of the WinRT calls force you to use async and await, which are only available in .NET 4.0.
So the next most logical thing to do was to create a native plugin.  But while I was exploring this options I came across a XAML to Unity connection example (http://docs.unity3d.com/Manual/windowsstore-examples.html).  Turns out this little example project shows how to wire up a communication bridge between your Windows Store App and Unity.  Just what I needed!

First in Unity add a new script called XAMLConnection to your Camera.

using UnityEngine;
using System.Collections;

public class XAMLConnection : MonoBehaviour
{	
	public delegate void OnEvent(object arg);
	
	public OnEvent onEvent = null;
	
	void Start () 
	{
		
	}
	
	void Update () 
	{
		
	}

Here are the steps to wire up your own Windows Store App to Unity bridge.

  1. Build your Unity Project.  Be sure to target the Windows Store build target and set the SDK to 8.1.
  2. You will be prompted for a target build folder.  Create a new folder called Windows8_1.
  3. Once the build is complete browse to your newly created Windows8_1 project and open the Visual Studio Solution file (the .sln file).
  4. Build and run the project in Visual Studio to verify you don’t have any issue before proceeding.  Would hate for you to think there was something wrong with this tutorial when it is really just some rotten code in your game 😉
  5. Now that we have verified the default build worked correctly we can begin modifying the app.  Open the MainPage.xaml.cs file

In the constructor add the following line:

UnityPlayer.AppCallbacks.Instance.Initialized += OnInitialized;

then add the OnInitalized, UnityToXAML and XAMLToUnity methods to the MainPage class

        private void OnInitialized()
        {
            Communications.SetEvent(UnityToXAML);
        }
        public void UnityToXAML(object arg)
        {
            UnityPlayer.AppCallbacks.Instance.InvokeOnUIThread(new UnityPlayer.AppCallbackItem(() =>
            {
                // Windows Store App code here               
            }
            ), false);
        }
       
        private void XAMLToUnity(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (UnityPlayer.AppCallbacks.Instance.IsInitialized())
            {
                UnityPlayer.AppCallbacks.Instance.InvokeOnAppThread(new UnityPlayer.AppCallbackItem(() =>
                {
                    //Unity code goes here ...
                    UnityEngine.GameObject go = UnityEngine.GameObject.Find("Camera");                    
                }
                ), false);
            }
        }

Now we add the delegate and class that link the Windows Store App and Unity together. The example has this in the MainPage.xaml.cs file – but out side of the MainPage class. The delegate and the Communications class are within the namespace but not in the MainPage class.

    public delegate void UnityEvent(object arg);
    public sealed class Communications
    {
        public static void SetEvent(UnityEvent e)
        {

             UnityPlayer.AppCallbacks.Instance.InvokeOnAppThread(new UnityPlayer.AppCallbackItem(() => 
                 {
                    UnityEngine.GameObject go = UnityEngine.GameObject.Find("Camera");
                    if (go != null)
                    {
                        go.GetComponent().onEvent = new XAMLConnection.OnEvent(e);
                    }
                    else
                    {
                        throw new Exception("Cube not found, have exported the correct scene?");
                    }
                 }), true);            
        }

Now run your project in Visual Studio. You now have a bridge between Unity and Windows Store Apps.