ユニバーサル Windows プラットフォーム: Association 起動
ユニバーサル Windows プラットフォーム: C# スクリプトで書いた WinRT API

AppCallbacks クラス

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);

このシンプルな XAML コントロールから Unity へのパスは DirectX 11 での対象の描画に使用されます。

appCallbacks->SetCoreWindowEvents(Window::Current->CoreWindow);

Unity に CoreWindow を設定すると Unity は次のイベントを扱えるようになります (最新のものではさらに増えている可能性があります)

  • VisibilityChanged
  • Closed
  • PointerCursor
  • SizeChanged
  • Activated
  • CharacterReceived
  • PointerPressed
  • PointerReleased
  • PointerMoved
  • PointerCaptureLost
  • PointerWheelChanged
  • AcceleratorKeyActivated

appCallbacks->InitializeD3DXAML();

これは Unity のためのメイン初期化関数で、次のことを行います。

  • Initializes DirectX 11 device
  • Loads first level

このとき Unity が最初のゲームステージの読み込みを完了した時点で、メインループを開始します。

その他の関数

  • void InvokeOnAppThread(AppCallbackItem item, bool waitUntilDone)

Invokes a delegate on application thread, which is useful when you want to execute your script function from UI thread.

  • void InvokeOnUIThread(AppCallbackItem item, bool waitUntilDone)

デリゲートの実行を UI スレッドへ依頼します。何かしらの XAML 固有 API をスクリプトから実行の依頼をしたい場合に使用します。

  • bool RunningOnAppThread()

アプリケーションスレッドで実行されている場合は true を返します。

  • bool RunningOnUIThread()

UI スレッドで実行されている場合は true を返します。

  • void InitializeD3DWindow()

D3D アプリケーションを初期化する関数です。

  • void Run()

D3D アプリケーションのメインループを開始するための関数です。

  • bool IsInitialized()

最初のゲームステージが完全に読み込まれていると true を返します。

  • void AddCommandLineArg(string arg)

アプリケーションのためにコマンドライン引数を設定します。InitializeD3DWindow()、InitializeD3DXAML() の前に呼ばれる必要があります。

  • void SetAppArguments(string arg) / string GetAppArguments()

Unity API から後でアクセスするためのアプリケーション引数を設定します - UnityEngine.WSA.Application.arguments

  • void LoadGfxNativePlugin(string pluginFileName)

この関数は、非推奨で動作しません。Unity の旧バージョンでは、UnityRenderEvent などでコールバックのネイティブプラグインを登録する必要がありました。現在は、すべてのプラグインが自動的に登録されます。この関数は今後のアップデートで削除されます。

  • void ParseCommandLineArgsFromFiles(string fileName)

コマンドライン引数をファイルから解析します。引数はスペースで区切られている必要があります。

  • bool UnityPause(int pause)

1 を渡すと Unity は一時停止し、0 を渡すと解除します。ゲームを一時的に停止させたい場合に使用します。例えばゲームのキャプチャを撮った場合などです。

  • void UnitySetInput(bool enabled)

入力の可否を切り替えます。

  • bool UnityGetInput()

Unity が入力を処理できる場合 ture を返します。

  • void SetKeyboardTriggerControl(Windows.UI.Xaml.Controls.Control ctrl)

スクリーンキーボードのトリガに使うコントロールを設定します。このコントロールはスクリプトからスクリーンキーボードが要求されるとシンプルなフォーカスを受け取ります。コントロールが呼ばれるとフォーカスされたキーボードをオープンします。

  • Windows.UI.Xaml.Controls.Control GetKeyboardTriggerControl()

キーボード入力のトリガとして使っているコントロールを返します。SetKeyboardTriggerControl を参照してください。

  • void SetCursor(Windows.UI.Core.CoreCursor cursor)

CoreWindow と独立した入力ソース (使用している場合) の両方にシステムカーソルを当てます。

  • void SetCustomCursor(unsigned int id)

CoreWindow と独立した入力ソース (使用している場合) の両方にカスタムのカーソルを当てます。パラメータにはカーソルのリソース ID を指定します。

ユニバーサル Windows プラットフォーム: Association 起動
ユニバーサル Windows プラットフォーム: C# スクリプトで書いた WinRT API