Unity 2023.1 から入った Android Project Configuration Managerについて理解する

これはUnity Advent Calendar 2023の8日目の記事です。

Unity 2023.1からUnityが出力するAndroidプロジェクトの、各種Gradleファイルや AndroidManifest.xml を、スクリプトから更新する「Android Project Configuration Manager」という機能が導入されました。

この機能は、現状のUnityで提供されている「Gradle template files」や IPostGenerateGradleAndroidProject の置き換えを想定して実装されています。

本記事では「Android Project Configuration Manager」について、その機能の概要から利用方法、既存機能との関係や移行方法を紹介します。

Android Project Configuration Manager とは

「Android Project Configuration Manager」は、Unityが出力するAndroidプロジェクトの各種Gradleファイル(build.gradlesetting.graldeなど)と AndroidManifest.xml をC#で操作するためのクラス群と、ビルドして出力されたAndroidプロジェクトの各種ファイルを更新するためのコールバックを提供します。

この機能を用いてAndroidアプリのビルド時に、各種Gradleファイルや AndroidManifest.xml を更新できます。

具体的には下記コードのようにAndroidProjectFilesModifierを継承したクラスの OnModifyAndroidProjectFiles 内でAndroidプロジェクトの更新処理を記述します。この引数で渡される AndroidProjectFiles がUnityが出力するAndroidプロジェクトの各種GradleファイルやAndroidManifest.xmlを表す変数で、この変数を用いてAndroidプロジェクトの更新を行います。

using System.IO;
using UnityEditor.Android;
using Unity.Android.Gradle;

public class ModifyProjectScript : AndroidProjectFilesModifier
{
    public override void OnModifyAndroidProjectFiles(AndroidProjectFiles projectFiles)
    {
        // Set minSdkVersion to 28
        projectFiles.UnityLibraryBuildGradle.Android.DefaultConfig.MinSdkVersion.Set(28);

        // Set android:enabled attribute to 'true' for all launcher activities
        var launcherActivities = projectFiles.UnityLibraryManifest.Manifest.GetActivitiesWithLauncherIntent();
        foreach (var activity in launcherActivities)
        {
            activity.Attributes.Enabled.Set(true);
        }
    }
}

たとえば上記コードでは、UnityLibrary側の build.gradleminSdkVersion28 に設定し、さらに AndroidManifest.xml 内のすべてのアクティビティの android:enabled 属性を true に設定しています。

C#のクラスで表現されているので、各種設定ファイルの変更がC#上で簡単に行えるようになりました。

なぜ Android Project Configuration Manager なのか

現状の「Gradle template files」や IPostGenerateGradleAndroidProject が提供されているなかで、なぜ「Android Project Configuration Manager」が導入されのか、について触れておきます。

まず、「Gradle template files」についての課題としてアップデート可能性(Upgradability)が挙げられます。

Unityのバージョンアップで内部で利用しているGradleそのものの更新が行われたり、機能追加や変更によって、期待するGraldeのテンプレートが変わることがあります。 具体的には、build.grale などの記述方法が変更されたり、テンプレートファイルへの変数の埋め込みが変わったりします。

このような変更があると、あわせてテンプレートファイルをメンテナンスする必要があります。 どのタイミングでテンプレートを更新すべきか、どのようにテンプレートを更新すべきかの判断を開発者が行う必要があり、これがAndroidのビルドパイプラインのメンテナンスコストを増加させる要因になっていました。 また、テンプレートファイルの齟齬による意図しない挙動やビルドエラーは気づきにくい、または対応の難易度が高いという問題もあります。

メンテナンス性や安定性を考えると、テンプレートとなる設定ファイルは露出させずにUnity側で管理し、出力されたAndroidプロジェクトに対して追記や変更を行う方式のほうが好ましく、このような機能が追加されたと考えられます。

このような課題の打ち手として IPostGenerateGradleAndroidProject が提供されていましたが、出力されたAndroidプロジェクトのルートパスが直接返却されるのみなので、Gradleファイルや AndroidManifest.xml を更新するためには独自のパーサーなどを用意する必要があるため、こちらも対応コストが高いという問題がありました。 そのため AndroidProjectFilesModifierOnModifyAndroidProjectFiles では、AndroidProjectFiles というAndroidプロジェクトを更新するためのクラスが提供して、API経由で各種設定の変更や更新が簡単に行えるようになりました。

これ以外にも、Unityが提供する、前回のビルド結果から変更点のみ更新してビルドを行うことでビルドの高速化を図るインクリメンタルビルドパイプライン互換性のための仕組みも用意されています

IPostGenerateGradleAndroidProject のあつかい

「Android Project Configuration Manager」が登場する以前から、Unityには IPostGenerateGradleAndroidProject というインターフェイスがあります。 IPostGenerateGradleAndroidProject を実装したクラスを用意することで、このインターフェイスが実装を要求する OnPostGenerateGradleAndroidProject メソッドがAndroidプロジェクト作成後に呼び出されます。

OnPostGenerateGradleAndroidProject の第1引数の path は、Unityの出力するAndroidプロジェクトのルートパスです。 実質「Android Project Configuration Manager」の提供する AndroidProjectFilesModifier の下位互換なため、Unity 2023.2からは IPostGenerateGradleAndroidProject インターフェイスの OnPostGenerateGradleAndroidProject メソッドは非推奨となっています

Unity - Scripting API: Android.IPostGenerateGradleAndroidProject.OnPostGenerateGradleAndroidProject

IPostGenerateGradleAndroidProject は将来的には呼び出されなくなる可能性があるため、IPostGenerateGradleAndroidProjectAndroidProjectFilesModifier を用いた実装に置き換えていく必要があります。

Gradle template files の移行と Android Templates Upgrader

「Android Project Configuration Manager」の導入で、テンプレートファイルを用いてGradleファイルを編集する「Gradle template files」は、テンプレートを用意しても出力されるAndroidプロジェクトには反映されなくなりました。 そのため「Gradle template files」でのGradleファイルの更新についても、AndroidProjectFilesModifier を用いた実装に置き換える必要があります。

Unity 2023ではこの移行を支援するために「Android Templates Upgrader」というウィンドウが用意されています。

ためしに下記のような minSdkVersion28 に明記した launcherTemplate.gradleAndroidProjectFilesModifier を用いた実装に移行してみます。

apply plugin: 'com.android.application'

dependencies {
    implementation project(':unityLibrary')
    }

android {
    ndkPath "**NDKPATH**"
    namespace "**NAMESPACE**"

    compileSdkVersion **APIVERSION**
    buildToolsVersion '**BUILDTOOLS**'

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
    }

    defaultConfig {
        // minSdkVersionを28に明示的に指定している
        minSdkVersion 28
        targetSdkVersion **TARGETSDKVERSION**
        applicationId '**APPLICATIONID**'
        ndk {
            abiFilters **ABIFILTERS**
        }
        versionCode **VERSIONCODE**
    }

    aaptOptions {
        noCompress = **BUILTIN_NOCOMPRESS** + unityStreamingAssets.tokenize(', ')
        ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~"
    }**SIGN**

    lintOptions {
        abortOnError false
    }

    buildTypes {
        debug {
            minifyEnabled **MINIFY_DEBUG**
            proguardFiles getDefaultProguardFile('proguard-android.txt')**SIGNCONFIG**
            jniDebuggable true
        }
        release {
            minifyEnabled **MINIFY_RELEASE**
            proguardFiles getDefaultProguardFile('proguard-android.txt')**SIGNCONFIG**
        }
    }**PACKAGING_OPTIONS****PLAY_ASSET_PACKS****SPLITS**
**BUILT_APK_LOCATION**
    bundle {
        language {
            enableSplit = false
        }
        density {
            enableSplit = false
        }
        abi {
            enableSplit = true
        }
        texture {
            enableSplit = true
        }
    }

	**GOOGLE_PLAY_DEPENDENCIES**
}**SPLITS_VERSION_CODE****LAUNCHER_SOURCE_BUILD_SETUP**

このテンプレートファイルを AndroidProjectFilesModifier に移行するには、Player Settings > Project Settings > Publishing Settings を開き、Build下の「Upgrade templates to C#...」というボタンを押します。 下図のように「Android Templates Upgrader」というウィンドウが開くので、「Custom Launcher Gradle Template」をチェックして「Upgrade Templates」ボタンを押します。

Android Tempates Upgrader

Android Tempates Upgrader

すると、下記のようなコードが Assets/Editor/Android/ModifyProjectScript.cs に生成されます。AndroidProjectFilesModifierminSdkVersion が正しく 28 に指定されていることが確認できます。

using System.Linq;
using UnityEditor;
using UnityEditor.Android;
using Unity.Android.Gradle;
using Unity.Android.Gradle.Manifest;
public class ModifyProjectScript : AndroidProjectFilesModifier
{
    public override void OnModifyAndroidProjectFiles(AndroidProjectFiles projectFiles)
    {
        projectFiles.LauncherBuildGradle.Android.DefaultConfig.VersionName.Remove();
        projectFiles.LauncherBuildGradle.Android.DefaultConfig.MinSdkVersion.Set(28);

    }
}

おわりに

Unity 2023.1から導入された「Android Project Configuration Manager」について、この概要から利用方法、既存機能からの移行について紹介しました。

既存の「Gradle template files」や IPostGenerateGradleAndroidProject を置き換えのための機能なため、移行が必要になります。 気になるのはサードパーティーライブラリで、個人的にはとくに External Dependency Manager for Unity あたりが気になっています。このあたりは後日、時間があれば確認して記事に出来ればと思います。

また、この機能した実例についても、そのうち取り上げられれば、と。(時間があれば...)

参考