You could call the AppCallbacks class a bridge between your main application and the Unity engine. Here, we’ll try to explain what every call to AppCallbacks exactly does. Let’s build solution and explore App.xaml.cpp and MainPage.xaml.cpp files.
App::App()
{
InitializeComponent();
SetupOrientation();
m_AppCallbacks = ref new AppCallbacks();
}
void App::OnLaunched(LaunchActivatedEventArgs^ e)
{
m_SplashScreen = e->SplashScreen;
InitializeUnity(e->Arguments);
}
void App::InitializeUnity(String^ args)
{
ApplicationView::GetForCurrentView()->SuppressSystemOverlays = true;
m_AppCallbacks->SetAppArguments(args);
auto rootFrame = safe_cast<Frame^>(Window::Current->Content);
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr && !m_AppCallbacks->IsInitialized())
{
rootFrame = ref new Frame();
Window::Current->Content = rootFrame;
#if !UNITY_HOLOGRAPHIC
Window::Current->Activate();
#endif
rootFrame->Navigate(TypeName(MainPage::typeid ));
}
Window::Current->Activate();
}
MainPage::MainPage()
{
m_SplashScreenRemovalEventToken.Value = 0;
m_OnResizeRegistrationToken.Value = 0;
InitializeComponent();
NavigationCacheMode = ::NavigationCacheMode::Required;
auto appCallbacks = AppCallbacks::Instance;
bool isWindowsHolographic = false;
#if UNITY_HOLOGRAPHIC
// If application was exported as Holographic check if the device actually supports it,
// otherwise we treat this as a normal XAML application
isWindowsHolographic = AppCallbacks::IsMixedRealitySupported();
#endif
if (isWindowsHolographic)
{
appCallbacks->InitializeViewManager(Window::Current->CoreWindow);
}
else
{
m_SplashScreenRemovalEventToken = appCallbacks->RenderingStarted += ref new RenderingStartedHandler(this, &MainPage::RemoveSplashScreen);
appCallbacks->SetSwapChainPanel(m_DXSwapChainPanel);
appCallbacks->SetCoreWindowEvents(Window::Current->CoreWindow);
appCallbacks->InitializeD3DXAML();
m_SplashScreen = safe_cast<App^>(App::Current)->GetSplashScreen();
auto dispatcher = CoreWindow::GetForCurrentThread()->Dispatcher;
ThreadPool::RunAsync(ref new WorkItemHandler([this, dispatcher](IAsyncAction^)
{
GetSplashBackgroundColor(dispatcher);
}));
OnResize();
m_OnResizeRegistrationToken = Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler([this](Object^, WindowSizeChangedEventArgs^)
{
OnResize();
});
}
}
m_AppCallbacks = ref new AppCallbacks();
Let’s take a closer look at AppCallbacks class. When you create it, Unity creates a new thread called “AppThread”. This is done because there’s a restriction from Microsoft - if your application does not become responsive after 5 seconds you’ll fail to pass WACK (Windows Application Certification). (You can read more here - http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184840(v=vs.105).aspx) Imagine if your first level is pretty big and takes a significant amount of time to load. Because your application is running on UI thread, the UI will be unresponsive until your level is fully loaded. That’s why Unity always runs your game on different thread.
Read more on the UI thread here - http://msdn.microsoft.com/en-us/library/windows/apps/hh994635.aspx
You can also pass custom command line arguments as string array into the AppCallbacks constructor.
Note: Code located in App.xaml.cpp, MainPage.xaml.c[[ is always running on UI thread, unless called from InvokeOnAppThread function.
appCallbacks->SetSwapChainPanel(m_DXSwapChainPanel);
Esto simplemente pasa un control XAML a Unity que será utilizado como un objetivo de render para DirectX 11.
appCallbacks->SetCoreWindowEvents(Window::Current->CoreWindow);
Configura el core window para Unity, Unity se suscribe a los siguientes eventos (puede haber más, dependiendo cuando esta información fue actualizada) :
appCallbacks->InitializeD3DXAML();
Esta es la función de inicialización principal para Unity, hace las siguientes cosas:
En este punto, cuando Unity termina de cargar el primer nivel, ingresa al bucle principal.
Invokes a delegate on application thread, which is useful when you want to execute your script function from UI thread.
Invoca un delegate en el UI thread, útil cuando quiere invocar algo a una API específica de XAML desde sus scripts.
Devuelve true, si actualmente está ejecutando en el application thread.
Devuelve true, si actualmente está ejecutando en el thread UI.
Función de inicialización para una aplicación D3D.
Función utilizada por una aplicación D3D, para ingresar en el main loop (bucle principal).
Devuelve true, cuando el primer nivel haya terminado de cargar.
Configura los argumentos de linea de comando para la aplicación, se deben llamar antes de InitializeD3DWindow, InitializeD3DXAML.
Configura los argumentos de la aplicación, que luego se pueden acceder desde la Unity API - UnityEngine.WSA.Application.arguments.
Esta función es obsoleta y no hace nada. En versiones anteriores de Unity, se necesitaba para registrar los plugins nativos para callbacks como UnityRenderEvent. Todos los plugins ahora están registrados automáticamente. Esta función será quitada en una actualización futura.
Parse argumentos de linea de comando de un archivo, los argumentos deben estar separados por espacios blancos.
Pausa Unity si usted pasa un 1, reanuda si pasa 0, útil si quiere congelar temporalmente su juego, por ejemplo., cuando su juego es snapped.
Habilita/Desactiva el input.
Devuelve true, si Unity va a procesar input entrante.
Configura el control que se utilizará para activar el teclado en pantalla. Este control simplemente recibirá enfoque, cuando el teclado en pantalla se solicite en scripts. Se debe llamar con control, que abra el teclado en foco.
Devuelve control el control actualmente utilizado para activar input del teclado. Mirar SetKeyboardTriggerControl.
Configura el cursor del sistema. El cursor dado se configura para ambas fuentes de input (si se utilizan) CoreWindow e independientes.
Configura el cursor del sistema a custom (personalizado). El parámetro es el ID de recursos del cursos. El cursor se configura para ambas fuentes de input (si se utilizan) CoreWindow e independientes.