はじめに
最近 Go/GearVR 向けに作っていた VR アプリを Quest にも対応させる機会がありました
その際 Go/GearVR と Quest の APK をそれぞれ出力する時に、
Go/GearVR と Quest の設定を切り替える度に ApplicationID
を変更したり、
外部サービスのコンフィグファイル差し替え作業等が必要になることが判明しました。。
更に改修の度に検証やリリース用として、Go/GearVR と Quest 用含め、
計6つも APK を出力することが必要になりました。。
仕方なく最初は手作業で APK を 6つ出力していたのですが、
それだけで 20分近くも時間がかかるようになってしまいました。。
(しかも手作業だと誤った APK を出力してしまう時もあり、そうなるとやり直し。。
流石にこのままだとマズイと感じたため、まずは APK 出力を Docker で自動化しました
Docker を採用した理由は様々な CI 環境に乗せようと思った時に好都合だからです
最終的に 6つの APK 出力にかかる時間は 20分 -> 10分 で完了するようになり、
誤った内容の APK が出力されることも無くなりました
本記事では APK 出力を Docker で自動化するために行った対策手順について書いていきます
動作環境
- Unity 2018.4.9f1
- Docker 19.03.5
アプリケーションの設定値を GUI で変更出来るようにする
まずは自動化を進めるにあたって、
EditorWindow
で GUI でアプリケーションの設定値が編集が出来るようにします。
GUI で設定した値は ScriptableObject
で管理出来るようにします。
ScriptableObject
でアプリケーションの設定値を管理可能にする
今回は下記をアプリケーションの設定値として定義します
- EnvironmentType (Enum):
STAGING
PRODUCTION
RELEASE
- DeviceType (Enum):
GEAR_VR_AND_GO
QUEST
EnvironmentType
は実行環境 (検証 / 本番 / リリース) が指定できる項目となります。
DeviceType
は実行端末 (GearVR or Go / Quest) が指定できる項目となります。
実行環境や実行端末に応じて API のリクエスト先変更したり、
クレデンシャルを変更したり出来るようになる想定で用意しました
また、アプリケーションの設定値を保存する際は、
実行端末を表す DeviceType
の値に応じて Oculus Platform の App ID も変更するようにします
早速アプリケーション設定値を管理するための ScriptableObject
を作成します
using System.IO;
using UnityEngine;
using UnityEditor;
// アプリケーションの設定値を管理するための ScriptableObject
public class ApplicationSetting : ScriptableObject
{
// 実行端末 (GearVR or Go / Quest) の Enum
public enum DeviceType
{
GEAR_VR_AND_GO, QUEST
}
// 実行環境 (検証 / 本番 / リリース) の Enum
public enum EnvironmentType
{
STAGING, PRODUCTION, RELEASE
}
// 実行端末 (GearVR or Go / Quest) を設定するための変数
// 値の変更は Editor 上からのみ許可する
[SerializeField]
private DeviceType _device;
public DeviceType Device
{
get { return _device; }
#if UNITY_EDITOR
set { _device = value; }
#endif
}
// 実行環境 (検証 / 本番 / リリース) を設定するための変数
// 値の変更は Editor 上からのみ許可する
[SerializeField]
private EnvironmentType _environment;
public EnvironmentType Environment
{
get { return _environment; }
#if UNITY_EDITOR
set { _environment = value; }
#endif
}
// ==========================================================
// Editor 内でしか利用しない定数や関数群
#if UNITY_EDITOR
// アプリケーションの設定値の保存先
const string ASSET_FILE_PATH = "Assets/Resources/ApplicationSetting.asset";
// GearVR もしくは Oculus Go 用の App ID
const string GEAR_VR_AND_GO_APPID = "1111111111111111";
// Quest 用の App ID
const string QUEST_APPID = "2222222222222222";
public static ApplicationSetting ReadFromEditor()
{
return AssetDatabase.LoadAssetAtPath<ApplicationSetting>(ASSET_FILE_PATH);
}
// アプリケーションの設定値を保存するために使用する関数
public void Save()
{
// アプリケーション設定を保存するファイルが存在しなければ新たに生成する
WriteFileIfNotExists();
// Device 変数の値を元に適切な AppID を Oculus Platform に設定する
SetAppID();
// Unity の Inspector からの設定変更を許可しない
this.hideFlags = HideFlags.NotEditable;
// ScriptableObject に変更があったことを記録する
EditorUtility.SetDirty(this);
// ScriptableObject の変更内容を保存する
AssetDatabase.SaveAssets();
// ScriptableObject をインポートし直す
AssetDatabase.Refresh();
}
// アプリケーションの設定値を保存するためのファイルを生成する関数
void WriteFileIfNotExists()
{
// 既にファイルが存在していれば処理を中断する
if (File.Exists(ASSET_FILE_PATH)) return;
// ASSET_FILE_PATH で指定された場所にファイルの実体を作成する
string directory = Path.GetDirectoryName(ASSET_FILE_PATH);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
AssetDatabase.CreateAsset(this, ASSET_FILE_PATH);
}
// Device 変数の値を元に Oculus Platform の App ID の値を設定するために使用する関数
void SetAppID()
{
string appId = "";
switch (this.Device)
{
case DeviceType.GEAR_VR_AND_GO:
appId = GEAR_VR_AND_GO_APPID;
break;
case DeviceType.QUEST:
appId = QUEST_APPID;
break;
}
Oculus.Platform.PlatformSettings.MobileAppID = appId;
}
#endif
}
アプリケーションの設定値を管理するスクリプトが出来たので、
次は EditorWindow
から設定が変更出来るようにします
EditorWindow
を利用して GUI からアプリケーションの設定値を変更可能にする
作成した ScriptableObject
の値を EditorWindow
から変更出来るようにします
using UnityEngine;
using UnityEditor;
// アプリケーションの設定値を編集できる画面を EditorWindow で作成する
public class ApplicationSettingWindow : EditorWindow
{
// アプリケーションの設定値を管理するための変数
private ApplicationSetting applicationSetting;
// メニューの Window -> Application Setting からアクセス可能にする
[MenuItem("Window/Application Setting")]
public static void Create()
{
// アプリケーションの設定値を編集できる画面を作成する
GetWindow<ApplicationSettingWindow>("Application Setting");
}
private void OnEnable()
{
// 画面が有効化され次第、アプリケーション設定値をファイルから読み込む
// ファイルから設定値が読み込めなかった場合は null が設定される
applicationSetting = ApplicationSetting.ReadFromEditor();
}
private void OnGUI()
{
// applicationSetting が正しく初期化されていなかったら、
// 新しくインスタンスを生成して applicationSetting に代入する
if (applicationSetting == null)
{
applicationSetting = ScriptableObject.CreateInstance<ApplicationSetting>();
}
// 画面に縦並びに実行環境設定用の選択リスト、実行端末設定用の選択リスト、Save ボタン (アプリケーション設定保存用ボタン) を配置する
using (new GUILayout.VerticalScope())
{
// 実行環境設定用の選択リストの値が変更される度に実行環境の値を設定する
applicationSetting.Environment =
(ApplicationSetting.EnvironmentType)EditorGUILayout.EnumPopup("Environment", applicationSetting.Environment);
// 実行端末設定用の選択リストの値が変更される度に実行端末の値を設定する
applicationSetting.Device =
(ApplicationSetting.DeviceType)EditorGUILayout.EnumPopup("Device", applicationSetting.Device);
// Save ボタンをクリックすることで、アプリケーションの設定値を保存 / 更新する
if (GUILayout.Button("Save"))
{
applicationSetting.Save();
}
}
}
}
上記スクリプトを Assets/Editor/ApplicationSettingWindow.cs
に配置すると、
Unity メニューの Window -> Application Setting
から、
アプリケーション設定値の編集画面に遷移することが出来るようになっているはずです

また、編集画面に遷移後、Environment
と Device
を適当な値に設定してから
Save
ボタンをクリックすると Resources
フォルダにアプリケーション設定値を保存するためのファイルが生成されます
アプリケーション設定値を保存するためのファイルが生成されたのを確認した後、
編集画面を開き直すと最後に更新した値が反映されていることが確認出来ます

更に Unity メニューの Oculus -> Platform -> Edit Settings
の Application ID
を見ると、
設定した Device
に応じて値が変化している様子が確認出来ます

Unity バッチモードで APK 出力が出来るようにする
次は Docker で APK 出力が出来るようにするために、
Unity バッチモード経由で APK 出力出来るようにします
APK の出力はプログラム経由でも実行することが可能です
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System;
using System.IO;
public class ApkBuilder
{
// 第一引数で指定したコマンドライン引数の値の 1つ後ろの値を取得するための関数
// 例: "-device QUEST" というパラメータの QUEST を取得したい場合は key に "-device" 文字列を指定する。
static string GetValueFromCommandLineArgs(string key) {
string[] args = System.Environment.GetCommandLineArgs();
for (int i = 0; i < args.Length; i++) {
if (key == args[i])
return args[i + 1];
}
return null;
}
public static void Build()
{
// Unity バッチモードで関数を実行する際は keystore の設定が無いので、
// コマンドライン引数から各種情報について渡すようにする必要がある
if (PlayerSettings.Android.keystoreName.Length == 0 ||
PlayerSettings.Android.keystorePass.Length == 0 ||
PlayerSettings.Android.keyaliasName.Length == 0 ||
PlayerSettings.Android.keyaliasPass.Length == 0)
{
PlayerSettings.Android.keystoreName = GetValueFromCommandLineArgs("-keystoreName");
PlayerSettings.Android.keyaliasName = GetValueFromCommandLineArgs("-keyaliasName");
PlayerSettings.Android.keystorePass = GetValueFromCommandLineArgs("-keystorePass");
PlayerSettings.Android.keyaliasPass = PlayerSettings.Android.keystorePass;
if (PlayerSettings.Android.keystoreName == null ||
PlayerSettings.Android.keyaliasName == null ||
PlayerSettings.Android.keystorePass == null)
{
Debug.LogError("Please set android keystore settings.");
return;
}
}
// Build Settings で設定シーンを全てビルドに含める
EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
List<string> scenePathList = new List<string>();
foreach (EditorBuildSettingsScene scene in scenes)
{
scenePathList.Add(scene.path);
}
var applicationSetting = ApplicationSetting.ReadFromEditor();
string device = applicationSetting.Device.ToString().ToLower();
string environment = applicationSetting.Environment.ToString().ToLower();
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
buildPlayerOptions.scenes = scenePathList.ToArray();
// プロジェクト直下の build フォルダに quest_production_20200202.apk のようなファイル名の APK を出力する
DateTime currentDate = DateTime.Now;
string dateString = $"{currentDate.Year}{currentDate.Month}{currentDate.Day.ToString("D2")}";
string outputDirectory = "build";
if (!Directory.Exists(outputDirectory))
{
Directory.CreateDirectory(outputDirectory);
}
buildPlayerOptions.locationPathName = $"{outputDirectory}/{device}_{environment}_{dateString}.apk";
buildPlayerOptions.target = BuildTarget.Android;
buildPlayerOptions.options = BuildOptions.None;
applicationSetting.Save();
BuildPipeline.BuildPlayer(buildPlayerOptions);
}
}
Assets/Editor/ApkBuilder.cs
スクリプト内の Build
関数は
キーストアが既に存在している前提の作りとなっているため、
まだキーストアを作っていない方は こちらの手順 に従って、
予めキーストアファイルとエイリアスの作成を行っておきましょう
また上記の ApkBuilder.Build
関数は Unity バッチモードからも実行出来ますが、
Editor 上からも実行出来るようになっています。
Editor 上からも APK 出力が確認できるようになっていると、
本当に正確な APK 出力が行われるかデバッグを行う際に便利です
そこで、早速 Editor 上からも実行できるように、
Assets/Editor/ApplicationSettingWindow.cs
に Build
ボタンを配置して、
ボタンをクリックしたら APK 出力出来るようにしてみましょう
using UnityEngine;
using UnityEditor;
// アプリケーションの設定値を編集できる画面を EditorWindow で作成する
public class ApplicationSettingWindow : EditorWindow
{
// アプリケーションの設定値を管理するための変数
private ApplicationSetting applicationSetting;
// メニューの Window -> Application Setting からアクセス可能にする
[MenuItem("Window/Application Setting")]
public static void Create()
{
// アプリケーションの設定値を編集できる画面を作成する
GetWindow<ApplicationSettingWindow>("Application Setting");
}
private void OnEnable()
{
// 画面が有効化され次第、アプリケーション設定値をファイルから読み込む
// ファイルから設定値が読み込めなかった場合は null が設定される
applicationSetting = ApplicationSetting.ReadFromEditor();
}
private void OnGUI()
{
// applicationSetting が正しく初期化されていなかったら、
// 新しくインスタンスを生成して applicationSetting に代入する
if (applicationSetting == null)
{
applicationSetting = ScriptableObject.CreateInstance<ApplicationSetting>();
}
// 画面に縦並びに実行環境設定用の選択リスト、実行端末設定用の選択リスト、Save ボタン (アプリケーション設定保存用ボタン) を配置する
using (new GUILayout.VerticalScope())
{
// 実行環境設定用の選択リストの値が変更される度に実行環境の値を設定する
applicationSetting.Environment =
(ApplicationSetting.EnvironmentType)EditorGUILayout.EnumPopup("Environment", applicationSetting.Environment);
// 実行端末設定用の選択リストの値が変更される度に実行端末の値を設定する
applicationSetting.Device =
(ApplicationSetting.DeviceType)EditorGUILayout.EnumPopup("Device", applicationSetting.Device);
// Save ボタンをクリックすることで、アプリケーションの設定値を保存 / 更新する
if (GUILayout.Button("Save"))
{
// Unity の Inspector からの設定変更を許可しない
applicationSetting.hideFlags = HideFlags.NotEditable;
// ScriptableObject に変更があったことを記録する
EditorUtility.SetDirty(applicationSetting);
applicationSetting.Save();
}
// Build ボタンをクリックし、ApkBuilder.Build 関数を実行することで、
// 現在のアプリケーション設定内容を元に APK をプロジェクト直下の build フォルダに生成する
if (GUILayout.Button("Build"))
{
ApkBuilder.Build();
}
}
}
}
これで Unity メニューの Window -> Application Setting
を開いた際に、
Build
ボタンが画面の最下部に表示されるようになったはずです
試しに Build
ボタンをクリックして APK 出力を行ってみましょう


下記のコマンドをターミナルで入力すると、
build
フォルダ内に APK が再度出力されること確認出来ると思います
(APK ファイルが上書きされて更新日時が新しくなっているはず
# Windows の場合
"C:\Program Files\Unity\Editor\Unity.exe" \
-quit -batchmode -projectPath ~/Desktop/CISample \
-executeMethod ApkBuilder.Build \
-keystoreName ~/Desktop/CISample.keystore -keyaliasName cisample \
-keystorePass CISample
# Mac の場合
/Applications/Unity/Hub/Editor/2018.4.9f1/Unity.app/Contents/MacOS/Unity \
-quit -batchmode -projectPath ~/Desktop/CISample \
-executeMethod ApkBuilder.Build \
-keystoreName ~/Desktop/CISample.keystore -keyaliasName cisample \
-keystorePass CISample
あとは Unity バッチモード経由で様々な設定の APK 出力が出来るように、
Assets/Editor/ApkBuilder.cs
を改修していきます
Unity バッチモードで引数を元に APK 出力の設定が出来るようにする
具体的には Assets/Editor/ApkBuilder.cs
に下記のような改修を行います
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System;
using System.IO;
using DeviceType = ApplicationSetting.DeviceType;
using EnvironmentType = ApplicationSetting.EnvironmentType;
public class ApkBuilder
{
// 第一引数で指定したコマンドライン引数の値の 1つ後ろの値を取得するための関数
// 例: "-device QUEST" というパラメータの QUEST を取得したい場合は key に "-device" 文字列を指定する。
static string GetValueFromCommandLineArgs(string key) {
string[] args = System.Environment.GetCommandLineArgs();
for (int i = 0; i < args.Length; i++) {
if (key == args[i])
return args[i + 1];
}
return null;
}
public static void Build()
{
var defaultApplicationSetting = ApplicationSetting.ReadFromEditor();
var applicationSetting = ApplicationSetting.ReadFromEditor();
// Unity バッチモードで実行時にコマンドライン引数の情報を元に
// Device と Environment の設定を変更出来るようにする
string deviceStringArg = GetValueFromCommandLineArgs("-device");
string environmentStringArg = GetValueFromCommandLineArgs("-environment");
if (deviceStringArg != null && environmentStringArg != null)
{
applicationSetting.Device = (DeviceType)Enum.Parse(typeof(DeviceType), deviceStringArg);
applicationSetting.Environment = (EnvironmentType)Enum.Parse(typeof(EnvironmentType), environmentStringArg);
}
// Unity バッチモードで関数を実行する際は keystore の設定が無いので、
// コマンドライン引数から各種情報について渡すようにする必要がある
if (PlayerSettings.Android.keystoreName.Length == 0 ||
PlayerSettings.Android.keystorePass.Length == 0 ||
PlayerSettings.Android.keyaliasName.Length == 0 ||
PlayerSettings.Android.keyaliasPass.Length == 0)
{
PlayerSettings.Android.keystoreName = GetValueFromCommandLineArgs("-keystoreName");
PlayerSettings.Android.keyaliasName = GetValueFromCommandLineArgs("-keyaliasName");
PlayerSettings.Android.keystorePass = GetValueFromCommandLineArgs("-keystorePass");
PlayerSettings.Android.keyaliasPass = PlayerSettings.Android.keystorePass;
if (PlayerSettings.Android.keystoreName == null ||
PlayerSettings.Android.keyaliasName == null ||
PlayerSettings.Android.keystorePass == null)
{
Debug.LogError("Please set android keystore settings.");
return;
}
}
// Build Settings で設定シーンを全てビルドに含める
EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
List<string> scenePathList = new List<string>();
foreach (EditorBuildSettingsScene scene in scenes)
{
scenePathList.Add(scene.path);
}
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
buildPlayerOptions.scenes = scenePathList.ToArray();
// プロジェクト直下の build フォルダに quest_production_20200202.apk のようなファイル名の APK を出力する
DateTime currentDate = DateTime.Now;
string dateString = $"{currentDate.Year}{currentDate.Month}{currentDate.Day.ToString("D2")}";
string outputDirectory = "build";
if (!Directory.Exists(outputDirectory))
{
Directory.CreateDirectory(outputDirectory);
}
string device = applicationSetting.Device.ToString().ToLower();
string environment = applicationSetting.Environment.ToString().ToLower();
buildPlayerOptions.locationPathName = $"{outputDirectory}/{device}_{environment}_{dateString}.apk";
buildPlayerOptions.target = BuildTarget.Android;
buildPlayerOptions.options = BuildOptions.None;
applicationSetting.Save();
BuildPipeline.BuildPlayer(buildPlayerOptions);
// Unity プロジェクトで元々設定していた内容にアプリケーション設定を戻す
defaultApplicationSetting.Save();
}
}
これで Unity バッチモードで ApkBuilder.Build
関数実行時に、
-device
と -environment
を指定した際に、
明示的にアプリケーション設定を指定した状態で APK を出力出来るようになりました
試しに Unity バッチモードで -device
と -environment
も引数に指定して APK 出力を行います
/Applications/Unity/Hub/Editor/2018.4.9f1/Unity.app/Contents/MacOS/Unity \
-quit -batchmode -projectPath ~/Desktop/CISample \
-executeMethod ApkBuilder.Build \
-keystoreName ~/Desktop/CISample.keystore -keyaliasName cisample \
-keystorePass CISample \
-device GEAR_VR_AND_GO -environment RELEASE
すると -device
と -environment
で指定した内容で APK が出力されているはずです

次は Docker コンテナで Unity バッチモードが実行できるようにします
Docker コンテナで Unity のバッチモード実行が出来るようにする
まずは Unity の Docker イメージを pull します
私は 2018.4.9f1 を使用していたので、tag が 2018.4.9f1-android
のイメージを pull しています
docker pull gableroux/unity3d:2018.4.9f1-android
Docker イメージのダウンロードが完了した後は、
下記コマンドで Docker コンテナを立ち上げて対話モードを起動します
# bash の場合
docker run -it --rm -e "UNITY_USERNAME=<Unity ID のユーザ名>" \
-e "UNITY_PASSWORD=<Unity ID のパスワード>" -e "TEST_PLATFORM=linux" \
-e "WORKDIR=/root/project" -e "$(pwd):/root/project" \
gableroux/unity3d:2018.4.9f1-android bash
# fish の場合
eval docker run -it --rm -e "UNITY_USERNAME=<Unity ID のユーザ名>" \
-e "UNITY_PASSWORD=<Unity ID のパスワード>" -e "TEST_PLATFORM=linux" \
-e "WORKDIR=/root/project" -e "(pwd):/root/project" \
gableroux/unity3d:2018.4.9f1-android bash
対話モードが正常に起動できたら下記コマンドで、
ライセンスのアクティベーションを要求するための xml を出力します
xvfb-run --auto-servernum --server-args='-screen 0 640x480x24' \
/opt/Unity/Editor/Unity -logFile -batchmode \
-username "$UNITY_USERNAME" -password "$UNITY_PASSWORD"
# ...
# 下記の Posting という出力の後ろにある xml を、
# Unity_v<バージョン>.alf という名前でファイルに保存する
LICENSE SYSTEM [202022 9:57:44] Posting <?xml version="1.0" encoding="UTF-8"?><root><SystemInfo><IsoCode>en</IsoCode><UserName>(unset)</UserName><OperatingSystem>...</MachineBindings><UnityVersion Value="2018.4.9f1" /></License></root>
# ...
私は Unity のバージョン 2018.4.9f1
を使用しているので、
Unity_v2018.4.9f1.alf
というファイル名で保存しました
その後、https://license.unity3d.com/manual へアクセスします
するとライセンスのアクティベーションを要求するためにファイルをアップロードするよう促されるので、
先程保存した Unity_v2018.4.9f1.alf
というファイルをアップロードします
アップロードして無事にアクティベーションの要求が成功すると、
Unity Plus or Pro
と Unity Personal Edition
のライセンス、
どちらをアクティベートするか聞かれるので選択して Next ボタンをクリックします
正常に認証が完了すれば、
Download license file
ボタンが出てくるので、クリックしてライセンスファイルをダウンロードします。
ライセンスファイルは Unity_v2018.x.ulf
という名前でダウンロードされます
これでようやく Docker コンテナ上で Unity バッチモードを実行する環境が整いました
早速 Unity プロジェクトビルド用の Dockerfile
を作成します
# Unity プロジェクトのバージョンと合わせて Unity バージョンは 2018.4.9f1 を使用する
# また Android プラットフォーム向けのビルドが行えるイメージを引っ張ってくる
FROM gableroux/unity3d:2018.4.9f1-android
LABEL maintainer="Admin <admin@nikaera.com>"
# Unity ライセンスファイルやキーストア、プロジェクトファイルを Docker イメージに内包する
COPY ./Unity_v2018.x.ulf /root/.local/share/unity3d/Unity/Unity_lic.ulf
COPY ./CISample.keystore /root/CISample.keystore
COPY ./unity /root/unity
# APK 出力のための関数への引数として DEVICE と APP_ENV という環境変数で
CMD /opt/Unity/Editor/Unity \
-quit -batchmode -nographics -logFile -projectPath /root/unity \
-executeMethod ApkBuilder.Build \
-keystoreName /root/CISample.keystore -keyaliasName cisample \
-keystorePass CISample \
-device $DEVICE -environment $APP_ENV
また Docker 導入にあたってプロジェクトのフォルダ構成は下記のようになっております
.
├── CISample.keystore # Android ビルド時に利用するキーストアファイル
├── Dockerfile # Docker イメージをビルド際に使用するファイル
├── Unity_v2018.x.ulf # Unity のライセンスファイル
└── unity # Unity プロジェクトフォルダを unity フォルダに移行する
├── Assembly-CSharp-Editor.csproj
├── Assembly-CSharp.csproj
├── Assets
├── CISample.sln
├── Library
├── Logs
├── Oculus.VR.Editor.csproj
├── Oculus.VR.Scripts.Editor.csproj
├── Oculus.VR.csproj
├── Packages
├── ProjectSettings
├── build
└── obj
Dockerfile
の内容を元にプロジェクトルートでターミナルから下記コマンドでイメージを作成します
docker build -t nikaera/cisample .
正常にイメージ作成出来たら試しに実際に Docker コンテナで APK を出力してみます
# APK 出力フォルダをホストと共有しておくことで出力した APK が参照出来るようにする
# 環境変数 DEVICE に QUEST、環境変数 APP_ENV に RELEASE を指定することで
# Quest のリリース版 APK を出力する。
docker run -v ~/Desktop/build:/root/unity/build --rm \
--env DEVICE=QUEST --env APP_ENV=RELEASE nikaera/cisample
正常に APK 出力出来ればデスクトップの build フォルダ内に quest_release_<日付>.apk
が出来ているはずです
Docker コンテナで全ての APK 出力を行う
ここまできたら後はスクリプト等で一気に全パターンの APK を出力します
まずは全 APK 出力を Docker コンテナで行うためのシェルスクリプトを作成します
#!/bin/bash
docker run -v $1:/root/unity/build --rm --env DEVICE=GEAR_VR_AND_GO --env APP_ENV=STAGING nikaera/cisample
docker run -v $1:/root/unity/build --rm --env DEVICE=GEAR_VR_AND_GO --env APP_ENV=PRODUCTION nikaera/cisample
docker run -v $1:/root/unity/build --rm --env DEVICE=GEAR_VR_AND_GO --env APP_ENV=RELEASE nikaera/cisample
docker run -v $1:/root/unity/build --rm --env DEVICE=QUEST --env APP_ENV=STAGING nikaera/cisample
docker run -v $1:/root/unity/build --rm --env DEVICE=QUEST --env APP_ENV=PRODUCTION nikaera/cisample
docker run -v $1:/root/unity/build --rm --env DEVICE=QUEST --env APP_ENV=RELEASE nikaera/cisample
シェルスクリプトを用意次第、下記コマンドで一気に APK を出力します
bash build.sh ~/Desktop/build
すると全実行環境及び全実行端末の APK が、
デスクトップの build
フォルダに生成されていること確認できるはずです
おわりに
今回は Docker コンテナで Unity バッチモードを動かして、
モバイル VR 向けの APK を一括で出力出来るようにしてみました。
Docker コンテナ上で Unity を動かすための
ライセンス発行処理周りの作業が面倒なので出来れば自動化したい。。
参考リンク
[Unity]KeyStore作成メモー
gableroux/unity3d
Unity の Android ビルドを CLI からおこなう
【Unity】GitHub Actions v2でUnity Test Runnerを走らせて、結果をSlackに報告する【入門】