こんにちは、エンジニアのオオバです。
スマホ端末でアプリが別のアプリの上で動作するのを見たことないでしょうか?
そう、それが今回のお題である 「Picture in Picture」 です。
具体的には次の画像のようなアプリをサスペンド状態(非アクティブ)にしても画面が縮小して動作する仕組みです。
※操作は不可、ただ見るだけ
ゲームより動画系のアプリで実装されている印象が強いです。
ということでこの記事ではUnityでPicture in Pictureを実装する方法を解説します。
ただし、この記事でサポートするプラットフォームはAndroidのみのためご注意を。
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実装の全体の流れ
まず最初に開発全体のイメージを掴んでもらうために大きな流れについて紹介します。
- Android向けUnityプロジェクトの作成
- Unityコンテンツを作成
- UnityエディタからAndroidプロジェクトの書き出し
- Android Studioでプロジェクトを開く
- AndroidManifest.xml修正
- Picture in Pictureコードを追加
- 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);
}
}
実行するとこんな感じで立方体がクルクル回ります。
※見栄えも考えて、立方体45度傾けて回してます。
以上で、Unityコンテンツの作成は終了です。
2.UnityエディタからAndroidプロジェクトの書き出し
次にUnityエディタからAndroidプロジェクトを書き出します。ここが最もUnityエディタ作業で重要なポイントです。
すでにAndroid向けのUnityプロジェクトを作っているはずなので、大丈夫だとは思いますが、念のためにBuild Targetが Android
になっていることを確認してみてください。
メニューFile -> Build Settings
からBuild Settingsウィンドウを開きます。
AndroidにUnityマークが付いていることを確認します。
もしAndroidにUnityマークが付いていない場合は、Androidを選択して、Switch Platformをクリックしてください。
ここではいくつか設定していきます。
Export Projectにチェックを入れる
通常、Unityエディタから直接Android端末にアプリをインストールする、またはAPKファイルを書き出しますが、今回はPicture in Picture処理をAndroid Studioで行うため、Androidプロジェクトを書き出します。
下記の画像のように Export Project
にチェックを入れましょう。
このままPlayer Settingsを開き、AndroidのOther Settingsを開きます。
下記3つの設定を行います。
- ①Package Nameを入力
- ②オオバの端末がARM64対応なのでARM64にチェック
- ③Picture in PictureはAndroid8以降の機能なので、Minimum API Levelを26以上に設定
上記の設定をして Export
ボタンを押します。
書き出し先を選ぶ必要があるため、Unityプロジェクトのルート階層に Build
というフォルダを作成して指定しました。
しばらくすると完了します。
Buildフォルダを開くとこんな感じでAndroidプロジェクトが書き出されます。
3.Android Studioでプロジェクトを開く
ここからはAndroid Studio側で作業です。
Android StudioのOpenボタンをクリック。UnityエディタからビルドされたAndroidプロジェクトを開きます。
どのディレクトリを指定すればよいか。
先ほどビルドした Build
フォルダを指定すればOKです。
以上で、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
です。
ダブルクリックして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
を開きます。
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
をクリック。
DeviceManagerのタブをVirtualからPhysicalに変更します。
Android実機の設定
次にテストするAndroid端末の 開発者向けオプションを有効化 します。
開発者オプションの有効化方法はこちらの記事を参考にしてみてください
→ Androidスマホ/タブレットで「開発者向けオプション」をオンにする
次にUSBデバッグを有効化します。
USBケーブルでパソコンとAndroid端末を接続してください。
※オオバはMacBookProを使用
すると、さきほどパソコンとUSB接続したAndroid端末(ここではGoogle Pixel7 Pro)が認識 & 表示されます。
Type
にUSBのマークが付いていることを確認してください(認識されたという意味です)。
もし、Android実機がAndroid Studioに認識されない場合は、こちらの記事を参考にチェックしてみてください。
ビルド
最後にビルドして実機で確認してみます。
メニューRun -> Run 'launcher'
をクリック。すると実機に直接アプリがインストールされ実行されます。
実際にアプリを起動すると以下のようにPicture in Pictureが動作します。
まとめ : 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つの表現手段として持っておくと良さそうですね。

筆者のXをフォローしよう
Unityオブジェクトの描画順の制御って難しいですよね。
この度、Unityの描画順を体系的に学べる「Unity描画順の教科書」を執筆しました。
Unityの描画順を基礎から学びたい方はぜひ確認してみてください!
→ Unity描画順の教科書
最後まで読んでいただきありがとうございました!
すばらしいUnityとPicture in Pictureライフをお過ごしください。
- Unity2022.3.21f1
- Android Studio Flamingo | 2022.2.1 Patch 2