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(User Interface) Allows a user to interact with your application. Unity currently supports three UI systems. More info
See in Glossary 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);
This simply passes a XAML control to Unity which will be used as a render target for DirectX 11.
appCallbacks->SetCoreWindowEvents(Window::Current->CoreWindow);
Sets the core window for Unity, Unity subscribes to the following events (there may be more, depending on when this information was updated) :
appCallbacks->InitializeD3DXAML();
This is main initialization function for Unity, it does following things:
At this point, when Unity finishes loading first level, it enters main loop.
Invokes a delegate on application thread, which is useful when you want to execute your script function from UI thread.
Invokes a delegate on UI thread, useful when you want to invoke something XAML specific API from your scriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary.
Returns true, if you’re currently running in application thread.
Returns true, if you’re currently running in UI thread.
Initialization function for D3D application.
Function used by D3D application, for entering main loop.
Returns true, when first level is fully loaded.
Sets a command line argument for application, must be called before InitializeD3DWindow, InitializeD3DXAML.
Sets application arguments, which can be later accessed from Unity API - UnityEngine.WSA.Application.arguments.
This function is obsolete and does nothing. In previous versions of Unity, this was needed to register native plugins for callbacks such as UnityRenderEvent. All plugins are now registered automatically. This function will be removed in a future update.
Parses command line arguments from a file, arguments must be separated by white spaces.
Pauses Unity if you pass 1, unpauses if you pass 0, useful if you want to temporary freeze your game, for ex., when your game is snapped.
Enables/Disables input.
Returns true, if Unity will process incoming input.
Sets the control to be used for triggering on screen keyboard. This control will simply receive focus, when on screen keyboard is requested in scripts. Should be called with control, that does open keyboard on focus.
Returns control, currently used control for triggering keyboard input. See SetKeyboardTriggerControl.
Sets system cursor. The given curosr is set for both CoreWindow and independent input source (if used).
Sets system cursor to custom. Parameter is cursor resource ID. Cursor is set for both CoreWindow and independent input source (if used).
When you visit any website, it may store or retrieve information on your browser, mostly in the form of cookies. This information might be about you, your preferences or your device and is mostly used to make the site work as you expect it to. The information does not usually directly identify you, but it can give you a more personalized web experience. Because we respect your right to privacy, you can choose not to allow some types of cookies. Click on the different category headings to find out more and change our default settings. However, blocking some types of cookies may impact your experience of the site and the services we are able to offer.
More information
These cookies enable the website to provide enhanced functionality and personalisation. They may be set by us or by third party providers whose services we have added to our pages. If you do not allow these cookies then some or all of these services may not function properly.
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us to know which pages are the most and least popular and see how visitors move around the site. All information these cookies collect is aggregated and therefore anonymous. If you do not allow these cookies we will not know when you have visited our site, and will not be able to monitor its performance.
These cookies may be set through our site by our advertising partners. They may be used by those companies to build a profile of your interests and show you relevant adverts on other sites. They do not store directly personal information, but are based on uniquely identifying your browser and internet device. If you do not allow these cookies, you will experience less targeted advertising. Some 3rd party video providers do not allow video views without targeting cookies. If you are experiencing difficulty viewing a video, you will need to set your cookie preferences for targeting to yes if you wish to view videos from these providers. Unity does not control this.
These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms. You can set your browser to block or alert you about these cookies, but some parts of the site will not then work. These cookies do not store any personally identifiable information.