しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

UWP アプリケーションを Xbox One 対応にするのは大変

対応プラットフォームとして Xbox One を入れておいた UWP アプリのレビューで動かないと指摘されたり、App Center のクラッシュログで Xbox One が目立つようになってきたので、少し真面目に対応してみました。

App Center は Xbox One でも問題なく使えているので便利でした。何故か Xbox One 向けはアプリバージョンが勝手に変わるのですが、App Center 上で区別がつきやすいので良いとします。

f:id:shiba-yan:20180212161133p:plain

ちゃんとデバイスの種類と OS バージョンも確認できます。

f:id:shiba-yan:20180212161028p:plain

とりあえず話を戻して Xbox One 向けにアプリを対応させる話です。

まず何を持って対応を謳えばいいのかアレだったので、ちゃんとドキュメントを読んで始めることに。

要はテレビに表示されることと、Xbox のコントローラでの操作を考慮すれば良さそうです。多分。

既に Xbox One への対応を行った先人の経験も参考にさせてもらいながら進めました。

とりあえず Xbox One 上ではコントローラを使った操作を考慮しないといけないのと、C# で書いた UWP アプリはデフォルトで 200% にスケーリング表示されるらしいので、そのあたりをオフにします。

ドキュメントにこの辺りは書いてあるので、その通りコードを追加します。

How to disable mouse mode - UWP app developer | Microsoft Docs
How to turn off scaling - UWP app developer | Microsoft Docs
How to draw UI to the edge of the screen - UWP app developer | Microsoft Docs

他にもテレビ表示用にオーバースキャンが有効化されていて、UWP アプリの四隅に謎のマージンが付いてしまって見栄えが悪いです。なので、その設定をオフにしておくと PC と同じように端まで表示されます。

上の設定は全て App.cs に書いておける内容なので修正は非常に楽でしたが、オーバースキャンをオフにすると AppBar の位置が変になってしまったので、今回のアプリではその設定は維持しました。

public sealed partial class App
{
    public App()
    {
        InitializeComponent();

        // マウスモードをオフに
        RequiresPointerMode = ApplicationRequiresPointerMode.WhenRequested;
    }

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        // スケーリングをオフに
        Windows.UI.ViewManagement.ApplicationViewScaling.TrySetDisableLayoutScaling(true);

        // オーバースキャンをオフに
        Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().SetDesiredBoundsMode(Windows.UI.ViewManagement.ApplicationViewBoundsMode.UseCoreWindow);

        // 初期化コード続き
}

これで最低限の表示と操作が行える UWP アプリになりました。

App Center のログを見るとアプリ内課金のタイミングで落ちていることが多かったので、ついでに原因を探ろうかと思っていたのですが、Xbox One は本番でしか IAP が行えないらしいです。

[UWP][XBOX]Are Add-ons supported on XBox one through universal apps?

デバッグ時に試せないのと、既に購入していると本番でも購入動作を確認できないので詰んだ感があります。

例外の内容的に Xbox One の場合は年齢制限などで課金が失敗することがあるのかと思ってましたが、現在は確認する方法がないので、とりあえず例外をハンドリングするぐらいにしました。