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

AppCallbacks クラス

ここでは、 AppCallbacks について解説します。 AppCallbacks はアプリケーションと Unity エンジンの橋渡しをするときに呼び出されます。まずはビルドを行い .NET Scripting Backend によって作成された App.xaml.cs ファイルを探してください。

sealed partial class App : Application
{
    private WinRTBridge.WinRTBridge _bridge;
    private AppCallbacks appCallbacks;
    public App()
    {
        this.InitializeComponent();
        appCallbacks = new AppCallbacks(false);
    }

    protected override void OnLaunched(LaunchActivatedEventArgs args)
    {
        Frame rootFrame = Window.Current.Content as Frame;
        if (rootFrame == null)
        {
            var mainPage = new MainPage();
            Window.Current.Content = mainPage;
            Window.Current.Activate();

            _bridge = new WinRTBridge.WinRTBridge();
            appCallbacks.SetBridge(_bridge);

            appCallbacks.SetSwapChainBackgroundPanel(mainPage.GetSwapChainBackgroundPanel());

            appCallbacks.SetCoreWindowEvents(Window.Current.CoreWindow);

            appCallbacks.InitializeD3DXAML();
        }

        Window.Current.Activate();
    }
}

private WinRTBridge.WinRTBridge _bridge;

WinRTBridge は Unity がネイティブからマネージドコードを呼び出す (native-to-managed) ために内部で使用します。マネージドコードからネイティブを呼び出す操作を開発者が利用することは想定されていません。WinRT プラットフォームの制限により Unity エンジンのコードからは生成されないため、代わりに WinRTBridge が生成され Unity へ appCallbacks.SetBridge(_bridge) を通して引き渡されます。

appCallbacks = new AppCallbacks(false);

AppCallbacks クラスに注目してみましょう。生成時にはゲームを別のスレッド上で動作するよう指定します。これは互換性のために行われます、 UI スレッドでアプリケーションを動作させることも可能ですがおすすめできません。これは Microsoft の制限 - アプリケーションは 5 秒以内に応答できなければ認証 WACK (Windows Application Certification) をパスできないためです。詳しくはここを参照 https://msdn.microsoft.com/ja-jp/library/windows/apps/hh184840.aspx、最初のゲームステージが大きくなってしまった場合を想像してみてください。アプリケーションが UI スレッドで実行されていると長時間の読み込みが行われるため、 UI は読み込みが完全に終わるまで応答無しとなるでしょう。これがゲームを別スレッド上で実行することをおすすめする理由です。

UI スレッド上の動作に関してはこちらも参照してください - http://msdn.microsoft.com/ja-jp/library/windows/apps/hh994635.aspx

補足: App.xaml.cs や MainPage.xaml.cs のコードは常に UI スレッドで動作し、InvokeOnAppThread 関数から呼ぶ必要はありません。

appCallbacks.SetSwapChainBackgroundPanel(mainPage.GetSwapChainBackgroundPanel());

このシンプルな 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 のためのメイン初期化関数で、次のことを行います。

  • コマンドライン引数を解析し、AppCallbacks.AddCommandLineArg() で設定します
  • DirectX 11 デバイスを初期化します
  • 最初のゲームステージを読み込みます

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

その他の関数

  • void InvokeOnAppThread(AppCallbackItem item, bool waitUntilDone)

デリゲートの実行をアプリケーションスレッドへ依頼します。スクリプトの実行を UI スレッドからの呼び出しを待って行いたい場合に使用します。

  • 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