Android
iOS
Unity
ios11
iPhoneX

2017年のスマホゲーム新解像度事情(+Unity対応方法)

【2017/09/22追記】
指摘いただき、Unityでxib出力の設定方法・xib出力時の場合を追記しました

2017年はスマホゲームの解像度周りで大きな更新がありました。
Android, iOS共に18:9以上のアスペクト比を持つ端末が出現しました。
Unityを例に概要と対応方法を載せます。

開発環境

  • macOS Sierra(10.12.6)
  • XCode9.0
  • Unity2017.1.0f3

Android

アプリをアップデートしてAndroidの新しいハイエンド端末で大きなアスペクト比を活用する
https://developers-jp.googleblog.com/2017/04/update-your-app-to-take-advantage-of.html

上記の記事の通り、2017年4月にGoogle Developersブログにて
ハイエンド端末で新アスペクト比を採用することが通知されました。

Device Aspect Ratio
Samsung Galaxy S8 18.5:9 (=2.1:1)
LG G6 18:9 (=2:1)

対応なしの状態だと16:9をベースに上下(横画面の場合は左右)に黒帯が入る状態になります。
(下図の左の状態)

追記: 黒帯が入る条件はresizableActivityでない場合です。targetSdkVersion24以上の場合はresizableActivityのデフォルトがtrueとなるため右の画面になります。

image00.png
(Google Developersブログより画像抜粋)

Androidフルスクリーン対応方法

18:9以上の端末でフルスクリーンで表示させるためにはAndroidManifest.xmlに以下を追加します。

<meta-data android:name="android.max_aspect" android:value="2.1" />

Unityであれば以下のパスに、デフォルトで使用されるAndroidManifest.xmlがあるので、
プロジェクトフォルダのAssets/Plugins/Android以下に配置します。

{Unity Folder}/PlaybackEngine/AndroidPlayer/Apk/AndroidManifest.xml

{My Project}/Assets/Plugins/Android/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
:
  <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="false">
  :
    <!-- 以下を追加 -->
    <meta-data android:name="android.max_aspect" android:value="2.1" />
:

iOS

iPhone X - Overview - iOS Human Interface Guidelines
https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/

スクリーンショット 2017-09-21 16.11.42.png
(iOS Human Interface Guidelinesより画像抜粋)

iOSもiPhone Xという18:9以上のアスペクト比を持つ端末が発表されました。
こちらは以下の制約もあります。

  • 四隅に丸みがあるため表示が一部隠れる
  • 上部分にカメラ・センサーがあるため表示が一部隠れる
  • 下部分はフリックするとホームの役割をするなどの理由でSafeAreaを設ける

Android同様に対応なしの状態だと16:9をベースに上下(横画面の場合は左右)に黒帯が入る状態になります。
iPhone X未対応でUnity2017.1でビルドをした場合、
Launch Screen Typeの設定によって、iPhone Xの表示は以下どれかの状態になります。

  • A. 正常に表示される、もしくは左右が見切れてしまう状態
  • B. 16:9をベースに上下(横画面の場合は左右)に黒帯が入る状態

Storyboard(xib)を出力する設定の場合、Aになります。
Storyboard(xib)を出力しない設定でiPhone X未設定の場合、Bになります。

これはiOSの解像度判定は以下となっているためです。

  1. Storyboard(xib)があればそれで判別
  2. Storyboard(xib)がなければImageSetで判別
  3. ImageSetがなければ480x320をベースに、必要あれば拡大表示

Unity2017.1でStoryboard(xib)を出力しない設定の場合、
iPhone XのImageSetは未設定でRetina HD 4.7(=iPhone6)は設定済のため
iPhone6ベースの16:9画面が使用されます。

スクリーンショット 2017-09-21 15.41.14.png
↑Unityが出力するiOSプロジェクトではiPhone Xの項目なし(未設定)

UnityのLaunchScreen設定オプション

Unity2017.1でStoryboard(xib)を出力する/しない設定にするには
iOS > Player Setting > Launch Screen Type
でLaunch Screenのxib出力設定を行います。Noneであれば出力なし。

スクリーンショット 2017-09-22 17.07.15.png

iOSプロジェクトを開いてxibファイルがあるかどうかで判別します。

スクリーンショット 2017-09-22 17.05.42.png

iOSフルスクリーン対応方法(Storyboard(xib)あり)

端末的にStoryboardありだとフルスクリーン状態になっているので表示が崩れる場合は以下を行います。

コードを見直す

端末的にはフルスクリーンになっているのでコードを変更します。
プレビュー画面で375x812(1125×2436)の端末を追加してプレビュー可能です。

スクリーンショット 2017-09-22 17.52.19.png

一時的に16:9表示にする

表示崩れを起こさないための一時対応として、
上記「UnityのLaunchScreen設定オプション」の通り
Storyboard(xib)を取り除き16:9の黒帯画面にします。

iOSフルスクリーン対応方法(Storyboard(xib)なし)

Storyboard(xib)がないプロジェクトでフルスクリーン対応する場合、
ImageSetを差し替えれば良いので、iOSプロジェクトのLaunchImageを新規作成しiPhone Xの欄に指定解像度の画像を設定します。

スクリーンショット 2017-09-21 15.47.43.png
↑XCode9.0で新規作成するとiPhone Xの欄があるため画像を設定する

Unity2017.1でiPhone Xの確認を行う方法

2017年9月時点では実機が発売前より、iOS SimulatorでiPhone Xを確認する方法をついでに載せます。

  1. XCodeの9.0以上をダウンロードします。
  2. iOS > Player Setting > Configurationで Target SDK をSimulatorSDKにします。
    スクリーンショット 2017-09-21 15.57.42.png

  3. iOSでビルドし、XCodeでプロジェクトを開きます。

  4. コード重複のビルドエラーになるので以下コメントアウトします。

Classes/Unity/UnityMetalSupport.h#L20

/*
typedef NSUInteger MTLPixelFormat;
enum
{
    MTLPixelFormatBGRA8Unorm,
    MTLPixelFormatBGRA8Unorm_sRGB,
};
*/
  1. iOS SimulatorでiPhone Xが選択可能になるので起動します

まとめ

Androidは未設定で、iOSはStoryboardがなければ
黒帯表示ありで表示崩れは起こらないようです。
しばらくは16:9のままで普及してきたら18:9対応を考えようと思いました。
以下まとめです。

  • 18:9以上のAndroid端末は、対応しないと16:9で黒帯表示となる
    • AndroidManifest.xmlでフルスクリーン対応する
  • 18:9以上のiOS端末(=iPhoneX)でStoryboard未設定のプロジェクトでは、対応しないと16:9で黒帯表示となる
    • UnityはPlayer SettingでLaunchScreenの設定を確認する
    • Storyboard未設定の場合でもImageSetでフルスクリーン対応可