読者です 読者をやめる 読者になる 読者になる

しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

Unity for UWP でアスペクト比を固定したレターボックス表示にする

Unity で UWP アプリを作る場合現状ではいろいろ制限が多いのですが、今回は UWP の方がやりやすい方法を試してみます

上記のように画面解像度に応じて縦横のアスペクト比を固定してレターボックス表示にしたい場合です

実は UWP ならこれはそんなに難しくありません

Unity Editor からビルドした UWP のプロジェクトを開くと MainPage.xaml が下記のようになっていると思います

<Page
    x:Class="NekoTank.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:NekoTank"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <SwapChainPanel x:Name="DXSwapChainPanel">
        <Grid x:Name="ExtendedSplashGrid" Background="#222C37">
            <Image x:Name="ExtendedSplashImage" Source="Assets/SplashScreen.png" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        </Grid>
    </SwapChainPanel>
</Page>

まずこれを下記のように、SwapChaninPanel を ViewBox で囲みます

<Page
    x:Class="NekoTank.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:NekoTank"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Viewbox>
        <SwapChainPanel x:Name="DXSwapChainPanel">
            <Grid x:Name="ExtendedSplashGrid" Background="#222C37">
                <Image x:Name="ExtendedSplashImage" Source="Assets/SplashScreen.png" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Grid>
        </SwapChainPanel>
    </Viewbox>
</Page>

さらに MainPage.xaml.cs のコードビハインドを次のように修正

/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
    private WinRTBridge.WinRTBridge _bridge;
        
    private SplashScreen splash;
    private Rect splashImageRect;
    private WindowSizeChangedEventHandler onResizeHandler;

    public MainPage()
    {
        this.Loaded += this.OnLoaded;

~ 中略 ~

    }

    /// <summary>
    /// 画面読み込み完了イベントハンドラ
    /// </summary>
    /// <param name="sender">イベント発行者</param>
    /// <param name="e">イベント引数</param>
    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        this.Loaded -= this.OnLoaded;
        this.OnSizeChanged(this, null);
        this.SizeChanged += this.OnSizeChanged;
    }

    /// <summary>
    /// 横のアスペクト比
    /// </summary>
    private static readonly double AspectWidth = 9d;

    /// <summary>
    /// 縦のアスペクト比
    /// </summary>
    private static readonly double AspectHeight = 16d;

    /// <summary>
    /// 画面サイズ変更イベントハンドラ
    /// </summary>
    /// <param name="sender">イベント発行者</param>
    /// <param name="e">イベント引数</param>
    private void OnSizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (Window.Current.Bounds.Height / Window.Current.Bounds.Width < AspectHeight / AspectWidth)
        {
            // 画面が 9:16 よりも横長な場合
            this.DXSwapChainPanel.Width = Math.Round(Window.Current.Bounds.Height * AspectWidth / AspectHeight);
            this.DXSwapChainPanel.Height = Window.Current.Bounds.Height;
        }
        else
        {
            // 画面が 9:16 ちょうどか縦長な場合
            this.DXSwapChainPanel.Width = Window.Current.Bounds.Width;
            this.DXSwapChainPanel.Height = Math.Round(Window.Current.Bounds.Width * AspectHeight / AspectWidth);
        }
    }

AspectWidth、AspectHeight には固定したい縦横のアスペクト比を指定します XAML 側の SwapChainPanel に Width/Height を指定する方法だと解像度の変化に追従できないので上記のように SizeChanged イベントを拾って Width/Height を調整するようにしました

すると

レターボックス表示でができました!

MainPage.xaml は比較的自由に扱えるので、例えば下記のように XAML に Background プロパティを追加すれば

<Page
    x:Class="NekoTank.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:NekoTank"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Background="#222C37"
    mc:Ignorable="d">

    <Viewbox>
        <SwapChainPanel x:Name="DXSwapChainPanel">
            <Grid x:Name="ExtendedSplashGrid" Background="#222C37">
                <Image x:Name="ExtendedSplashImage" Source="Assets/SplashScreen.png" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Grid>
        </SwapChainPanel>
    </Viewbox>
</Page>

すき間の背景色を変えたりできます

f:id:matatabi_ux:20160214121929p:plain

すき間に画像を表示したりもできますね