渋谷ほととぎす通信

エンジニア社長によるUnityとAIのブログ & エンジニアの生存戦略

UnityでPicture in Pictureを実装する方法(Android編)

UnityでPicture in Pictureを実装する方法(Android編)

こんにちは、エンジニアのオオバです。

お悩みさん
お悩みさん
  • UnityでPicture in Pitureする方法がわからない
  • UnityでPicture in Pictureってできるの?
  • オオバ
    オオバ
    本記事ではこれらの悩みを解決します。

    スマホ端末でアプリが別のアプリの上で動作するのを見たことないでしょうか?
    そう、それが今回のお題である 「Picture in Picture」 です。

    具体的には次の画像のようなアプリをサスペンド状態(非アクティブ)にしても画面が縮小して動作する仕組みです。
    UnityでPicture in Pictureを実装する方法(Android編)_0
    ※操作は不可、ただ見るだけ

    ゲームより動画系のアプリで実装されている印象が強いです。

    ということでこの記事ではUnityでPicture in Pictureを実装する方法を解説します。
    ただし、この記事でサポートするプラットフォームはAndroidのみのためご注意を。

    Unity×Picture in Pictureは一見難しそうだけど簡単!6ステップで実装可能

    はじめに結論を簡単にまとめます。

    Unity×Picture in Pictureは一見難しそうだけど簡単!6ステップで実装可能}

    ①たった6ステップでPicture in Pictureは実装可能

    ②プログラミングは数行だけ

    ③UnityエディタとAndroidStudioを使う

    一見Picture in Pictureって難しそうですが、意外と簡単です。
    「オオバさんだから簡単なんでしょ?」って思われるかもしれませんが、本当にやることはシンプルです。

    今回はUnityエディタとAndroid Studio両方使います。もし、今までの開発でAndroid Studioを使ったことがない方はラッキーかも知れません。使ってみるチャンスです。

    何事も触ってみないと、どんな具合かはわからないですよね。

    話しを戻しまして、これからUnityでPicture in Pictureの実装をめちゃくちゃ分かりやすく解説していますので、ぜひ最後まで読んでみてください。

    👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!

    Unity×Picture in Picture実装の全体の流れ

    まず最初に開発全体のイメージを掴んでもらうために大きな流れについて紹介します。

    1. Android向けUnityプロジェクトの作成
    2. Unityコンテンツを作成
    3. UnityエディタからAndroidプロジェクトの書き出し
    4. Android Studioでプロジェクトを開く
    5. AndroidManifest.xml修正
    6. Picture in Pictureコードを追加
    7. Android向けにビルド

    以上の6ステップでPicture in Pictureを実装します。
    正直、ソースコードは数行しか書きません。今回は自動化はせずに泥くらいやり方で紹介するため、Unityだけでは完結せず、Android Studioを使います。

    では早速、開発を進めていきましょう。

    0. Android向けUnityプロジェクトの作成

    今回はAndroid環境でPicture in Pictureを実装するため、Android向けのUnityプロジェクトを作成します。

    Android向けのUnityプロジェクトの作成方法については↓次の記事で解説していますので、わからない方はこちらを参考にしてみてください。

    1.Unityコンテンツを作成

    最初にUnityでPicture in Picture時でも表示したいコンテンツを作成します。
    今回は立方体がクルクル回るシンプルなコンテンツを作成します。

    立方体のGameObjectに以下のコンポーネントをセットします。

    using System.Collections;  
    using System.Collections.Generic;  
    using UnityEngine;  
    
    public class Sample : MonoBehaviour  
    {
        void Update()  
        {
            transform.localEulerAngles += new Vector3(0, 60f * Time.deltaTime, 0);  
        }
    }
    

    UnityでPicture in Pictureを実装する方法(Android編)_1
    実行するとこんな感じで立方体がクルクル回ります。
    ※見栄えも考えて、立方体45度傾けて回してます。

    以上で、Unityコンテンツの作成は終了です。

    2.UnityエディタからAndroidプロジェクトの書き出し

    次にUnityエディタからAndroidプロジェクトを書き出します。ここが最もUnityエディタ作業で重要なポイントです。

    すでにAndroid向けのUnityプロジェクトを作っているはずなので、大丈夫だとは思いますが、念のためにBuild Targetが Android になっていることを確認してみてください。

    メニューFile -> Build SettingsからBuild Settingsウィンドウを開きます。
    AndroidにUnityマークが付いていることを確認します。
    UnityでPicture in Pictureを実装する方法(Android編)_2

    もしAndroidにUnityマークが付いていない場合は、Androidを選択して、Switch Platformをクリックしてください。

    ここではいくつか設定していきます。

    Export Projectにチェックを入れる

    通常、Unityエディタから直接Android端末にアプリをインストールする、またはAPKファイルを書き出しますが、今回はPicture in Picture処理をAndroid Studioで行うため、Androidプロジェクトを書き出します。

    下記の画像のように Export Project にチェックを入れましょう。
    UnityでPicture in Pictureを実装する方法(Android編)_3

    このままPlayer Settingsを開き、AndroidのOther Settingsを開きます。
    UnityでPicture in Pictureを実装する方法(Android編)_4

    下記3つの設定を行います。

    UnityでPicture in Pictureを実装する方法(Android編)_5

    • ①Package Nameを入力
    • ②オオバの端末がARM64対応なのでARM64にチェック
    • ③Picture in PictureはAndroid8以降の機能なので、Minimum API Levelを26以上に設定

    上記の設定をして Export ボタンを押します。

    書き出し先を選ぶ必要があるため、Unityプロジェクトのルート階層に Build というフォルダを作成して指定しました。
    UnityでPicture in Pictureを実装する方法(Android編)_6

    しばらくすると完了します。
    Buildフォルダを開くとこんな感じでAndroidプロジェクトが書き出されます。
    UnityでPicture in Pictureを実装する方法(Android編)_7

    3.Android Studioでプロジェクトを開く

    ここからはAndroid Studio側で作業です。

    UnityでPicture in Pictureを実装する方法(Android編)_8
    Android StudioのOpenボタンをクリック。UnityエディタからビルドされたAndroidプロジェクトを開きます。

    どのディレクトリを指定すればよいか。
    先ほどビルドした Build フォルダを指定すればOKです。

    UnityでPicture in Pictureを実装する方法(Android編)_9

    以上で、Android StudioでAndroidプロジェクトを開くことができました。

    4.AndroidManifest.xml修正

    次に、AndroidManifest.xmlを修正します。
    そもそもAndroidManifest.xmlとは何かというと、Androidアプリを作成するときには必須のファイルです。
    ビルドする際に必要な情報が記載されています。

    今回実装するPicture in PictureもこのAndroidManifest.xmlを編集することになります。

    AndroidManifest.xmlはどこにあるのか?

    AndroidManifest.xmlはAndroidプロジェクト内のどこにあるのでしょうか?

    答えはここ→ unityLibrary/manifests/AndroidManifest.xml です。

    UnityでPicture in Pictureを実装する方法(Android編)_10

    ダブルクリックしてAndroidManifest.xmlを開きます。

    追加するのは、次のたった一行です。

    android:supportsPictureInPicture="true"  
    

    この一行を <activity android:name="com.unity3d.player.UnityPlayerActivity" のパラメーターに追加します。次サンプルを参考に編集してみてください。

    <activity android:name="com.unity3d.player.UnityPlayerActivity"  
            android:theme="@style/UnityThemeSelector"  
            android:screenOrientation="fullUser"  
            android:launchMode="singleTask"  
            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"  
            android:resizeableActivity="false"  
            android:hardwareAccelerated="false"  
            android:exported="true"  
            android:supportsPictureInPicture="true">  
    

    以上でAndroidManifest.xmlの編集は完了です。

    AndroidManifest全文はこちらのGist:AndroidManifest.xmlに貼っておきますので参考にどうぞ。

    5.Picture in Pictureコードを追加

    アプリがサスペンドしたら、Picture in Pictureするように処理を追加しています。
    どのファイルを編集したらよいか。

    unityLibrary/java/com.unity3d.player/UnityPlayerActivity.java を開きます。

    UnityでPicture in Pictureを実装する方法(Android編)_11

    UnityPlayerActivity.java を開いたら、3箇所Javaコードを修正します。
    面倒くさい人は、全文こちらのGist:UnityPlayerActivity.javaにアップしていますので、参考にどうぞ。

    その1.import文の追加

    Picture in Picture処理を実行するためのクラスを参照するために、import文に下記2行を追加します。追加する箇所は UnityPlayerActivity.java の冒頭です。

    import android.app.PictureInPictureParams;
    import android.util.Rational;
    

    その2.Picture in Picture実行処理を追加

    UnityPlayerActivity クラス内に下記のメソッドを追加します。

    private void startPictureInPicture() {  
        Rational rational = new Rational(mUnityPlayer.getWidth(), mUnityPlayer.getHeight());  
        PictureInPictureParams params = new PictureInPictureParams.Builder()  
                .setAspectRatio(rational)  
                .build();  
        enterPictureInPictureMode(params);  
    }
    

    その3.onPauseメソッドからPicture in Pictureを実行

    最後に onPause メソッド内の処理を修正します。
    onPauseメソッドを下記のように修正してください。具体的にはonPauseメソッドから startPictureInPicture メソッドを実行することでサスペンド時にPicture in Pictureが実行されるようになります。

    @Override protected void onPause()  
    {
        super.onPause();  
    
        MultiWindowSupport.saveMultiWindowMode(this);  
    
        if (MultiWindowSupport.isInMultiWindowMode(this))  
            return;  
    
        startPictureInPicture();  
        mUnityPlayer.resume();  
    }
    

    以上でソースコードの追加、修正は完了です。

    6.Android向けにビルド

    最後にビルド。Android Studioから直接Android実機にアプリをインストールします。

    Device Managerの設定

    メニューTools -> DeviceManager をクリック。
    UnityでPicture in Pictureを実装する方法(Android編)_12

    DeviceManagerのタブをVirtualからPhysicalに変更します。
    UnityでPicture in Pictureを実装する方法(Android編)_13

    Android実機の設定

    次にテストするAndroid端末の 開発者向けオプションを有効化 します。
    UnityでPicture in Pictureを実装する方法(Android編)_14

    開発者オプションの有効化方法はこちらの記事を参考にしてみてください
    Androidスマホ/タブレットで「開発者向けオプション」をオンにする

    次にUSBデバッグを有効化します。
    UnityでPicture in Pictureを実装する方法(Android編)_15

    USBケーブルでパソコンとAndroid端末を接続してください。
    UnityでPicture in Pictureを実装する方法(Android編)_16
    ※オオバはMacBookProを使用

    すると、さきほどパソコンとUSB接続したAndroid端末(ここではGoogle Pixel7 Pro)が認識 & 表示されます。

    UnityでPicture in Pictureを実装する方法(Android編)_17
    Type にUSBのマークが付いていることを確認してください(認識されたという意味です)。

    もし、Android実機がAndroid Studioに認識されない場合は、こちらの記事を参考にチェックしてみてください。

    ビルド

    最後にビルドして実機で確認してみます。

    UnityでPicture in Pictureを実装する方法(Android編)_18
    メニューRun -> Run 'launcher' をクリック。すると実機に直接アプリがインストールされ実行されます。

    実際にアプリを起動すると以下のようにPicture in Pictureが動作します。

    まとめ : UnityでPicture in Pictureを実装する方法(Android編)

    最後に記事の内容を簡単にまとめます。

    UnityでPicture in Pictureを実装する方法(Android編)

    ①UnityエディタからAndroidプロジェクトをExport(自動化しない場合)

    ②AndroidManifest.xmlにPicture in Picture許可コード追加

    ③AndroidのonPauseでPicture in Pictureを起動

    こんな感じです。

    今回は自動化を一切しない、泥臭い方法でPicture in Pictureを実装してみました。Unity側でAndroidManifestやAndroidプラグインを記述することでAndroidStudioを経由することなくUnityエディタだけで完結はすると思います。

    この記事はあくまで、基礎から学ぶをコンセプトに執筆していますので、自動化はまた別の機会に。

    Picture in Pictureはサクッと実装できちゃうので、ゲームやアプリの1つの表現手段として持っておくと良さそうですね。

    Unityオブジェクトの描画順の制御って難しいですよね。
    この度、Unityの描画順を体系的に学べる「Unity描画順の教科書」を執筆しました。

    Unityの描画順を基礎から学びたい方はぜひ確認してみてください!
    Unity描画順の教科書

    最後まで読んでいただきありがとうございました!
    すばらしいUnityとPicture in Pictureライフをお過ごしください。

    オススメ記事
    検証環境
    • Unity2022.3.21f1
    • Android Studio Flamingo | 2022.2.1 Patch 2
    参考サイト