Communicating with the UI thread using Windows 10 Universal, and il2cpp

I am working on a Windows Store game using il2cpp and would like invoke events on the UI thread from the game thread. I have been studying the XAMLUnityConnection example in the Unity Manual (Windows Store 8.1 not Windows Store 10). In that example the App UI thread can find Unity game objects on the Unity Game thread and register to receive events:

MainPage.xaml.cs

using UnityEngine.Windows;

public delegate void UnityEvent(object arg);
public sealed class Communications{
public static void SetEvent(UnityEvent e)
{
UnityEngine.GameObject go = UnityEngine.GameObject.Find("Cube");
if (go != null)
{
go.GetComponent<XAMLConnection>().onEvent = new XAMLConnection.OnEvent(e);
}
else
{
throw new Exception("Cube not found, have exported the correct scene?");
}
}
}

My problem is that the UnityEngine.Windows namespace does not exist in an il2cpp project so I cannot find Unity Game Objects. Is this the case? Do I need to add a reference or something to find this namespace?

That is correct, that namespace is a C# namespace - it’s not accessible from C++.

You can use UnityEngine.Windows.Application.InvokeOnUIThread() function to invoke code on UI thread directly from your game scripts. Does that not work?

1 Like

Thanks! I didn’t know about the UnityEngine.Windows.Application class. I will give this a try.

Hi Tautvydas,

I tried using UnityEngine.Windows.Applications.InvokeOnUIThread() but couldn’t figure out how to get it working with il2cpp. I read this thread How do I access my App.cs methods from my Unity scripts? - Unity Engine - Unity Discussions explaining how to do it in C#. It involves creating an interface and a Singleton of that type on the App thread. Then assigning the singleton from the UI thread and invoking its methods from the App thread.

In the il2cpp project the interface appears to be split into three different structs and the interface methods are put in a giant lookup table. Its not a simple abstract class like I was expecting. My C++ skills arn’t strong enough to figure out how to implement the interface.

Thanks for the tip though.

I don’t quite understand what the problem is now?
Do you want to call things on UI thread from Unity script or from main application?
From main application it will be simple, just call InvokeOnUIThread from UnityPlayer.AppCallbacks class.

It will be tougher from script, as you probably want to use some WinRT API. It would probably be simpler to write native plugin as a bridge. Your C# script would P/Invoke function from native plugin, while main application could set delegates in the same plugin, while plugin itself would invoke those delegates.

Ultimately I want to be able to invoke things on the UI thread from a Unity script.

I had forgotten about the native plugin. I had written one earlier but stopped when I discovered the XAMLUnityConnection example and thought I would be able do what I needed from Unity scripts. Now that you mention it I should be able to do the communication I need in the native plugin.

Thanks again for you help.

You just call it from your C# script. There’s no C++ step involved yet: your call will get converted to C++ after you press build in Unity… Something like this:

class MyScript : MonoBehaviour
{
    void Start()
    {
        UnityEngine.Application.InvokeOnUIThread(() =>
        {
            // do whatever you want on UI thread in C#
        }, false);
    }
}

The thread you read about “XAML connection” and “How to access unity scripts from VS project” will not apply here. It’s possible to do, but it is a little bit more complicated than that.

1 Like

Thanks, this worked beautifully!

I was imagining that I needed a method in the UI class that I could call using InvokeOnUIThread.

Thanks.