UE5.5で使用するAdmobをアップデートする方法
Unreal EngineでAdmobを使用する際、インストールしたばかりのUE5.5やUE5.4ではGameActivity.javaがエラーを起こして使えないといった問題が起こると思います。
今回は、この問題を修正します。また、デフォルトで使用しているGoogle Mobile Ads SDKが古いのでそのアップデート方法についても解説します。修正後のファイルに関しては、ページの最後にgithubリンクを載せています。
前提
記事の対象
この記事はAndroidデバイスでUnreal Engineプロジェクトを開発するための要件を満たしている方を対象にしています。
Admobを使用していない状態で、クイック起動できれば大丈夫です。
まだの方はUEのドキュメントを参考に要件を満たしてください。
(英語版と日本語版ではAndroid Studioのバージョンが違うので見比べながら設置すると良いと思います。)
Android上でUE製のゲームが動く仕組みについての概略
通常AndroidアプリはJavaやKotolinなどで記述します。一方、UEではC++を記述してゲームを作成します。こういった環境では、Andoridでアプリ起動時に、Javaにより仮想マシンが生成されその中でゲームが実行されます。また、Javaとネイティブコード(C++コンパイルにより作成されたコード)を結びつける仕組みであるJNI(Java Native Interface)によって端末で発生したイベントをゲームに通知したり、ゲームで発生したしたイベントをJava側に通知することができます。
Unreal Engineでは各モジュール内に記述されているJavaコードを集めて、ppGameActivity.javaを生成する仕組みが実装されており、Android上でゲームを動かすことができます。このGameActivity.javaはAndroidプラットフォームを対象とするプロジェクトごとに生成されます。以下のパスで実装が確認できます。
プロジェクトフォルダ/Intermediate/Android/arm64/src/com/epicgames/unreal/GameActivity.java
Admobの実装に関して
以下のフォルダ内で実装されていることが確認できます。
(UE_〇.〇の箇所はエンジンのバージョンを入れてください。 UE_5.5など)
UE_○.○/Engine/Source/Runtime/Advertising/Android/AndroidAdvertising
UEでは、Javaコードはxmlファイルに直書きされているため、このフォルダ内にあるファイルAndroidAdvertising_APL.xml
を修正していくことでAdmobのアップデートが可能になります。
GameActivity.javaのエラーについての対処
エラー内容
エンジンをインストールしてデフォルトの状態で、Admobの使用を開始するとパッケージ時に以下のようなエラーが発生します。
一部抜粋
> Task :app:compileDebugJavaWithJavac
Z:\app\src\main\java\com\epicgames\unreal\GameActivity.java:867: �G���[: �V���{�����������܂���
activityContext.runOnUiThread(new Runnable()
^
�V���{��: ���\�b�h runOnUiThread(<anonymous Runnable>)
�ꏊ: �^�C�vContextWrapper�̕ϐ� activityContext
対処
以下のパスにあるAndroidAdvertising_APL.xml
を修正することで直すことができます。
(UE_〇.〇の箇所はエンジンのバージョンを入れてください。UE_5.5など)
パス UE_○.○/Engine/Source/Runtime/Advertising/Android/AndroidAdvertising/AndroidAdvertising_APL.xml
おそらく全部で6箇所あるので全て以下のように修正してください。
- activityContext.runOnUiThread(new Runnable()
+ _activity.runOnUiThread(new Runnable()
xmlファイル修正後、Admobの設定をした上で、クイック起動を試してみるとエラーが出ずに実行できると思います。
解説
GameActivity.java
よりactivityContext
はContextWrapperクラスだとわかります。
protected ContextWrapper activityContext = null;
runOnUiThread
はActivityクラスのメソッドなので、_activity
に修正することで直せます。
Admobのアップデート
Google Mobile Ads SDKについてデフォルトでは18.1.0を使用していますが、最新では23.6.0なのでそちらに更新します。
また、20.0.0で従来のInterstitial APIが削除されたことや、AdListenerでのonAdFailedToLoadに変更があったようなので、そちらも更新します。
Google Mobile Ads SDKの更新
dependencies {
- implementation('com.google.android.gms:play-services-ads:18.1.0')
- implementation('com.google.android.gms:play-services-ads-identifier:18.0.1')
+ implementation('com.google.android.gms:play-services-ads:23.6.0')
}
onAdFailedToLoadの更新
- public void onAdFailedToLoad(int errorCode)
+ public void onAdFailedToLoad(LoadAdError adError)
インタースティシャル広告の更新
- import com.google.android.gms.ads.InterstitialAd;
+ import androidx.annotation.NonNull;
+ import com.google.android.gms.ads.LoadAdError;
+ import com.google.android.gms.ads.interstitial.InterstitialAd;
+ import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
// インタースティシャル広告インスタンスの生成部分と、UnitId設定部分の削除
- interstitialAd = new InterstitialAd(this);
- interstitialAd.setAdUnitId(AdMobAdUnitID);
// Runnableのrun関数内
- interstitialAd.loadAd(interstitialAdRequest);
+ InterstitialAd.load(
+ _activity,
+ AdMobAdUnitID,
+ interstitialAdRequest,
+ new InterstitialAdLoadCallback() {
+ @Override
+ public void onAdLoaded(@NonNull InterstitialAd ad) {
+ interstitialAd = ad;
+ isInterstitialAdLoaded = true;
+ isInterstitialAdRequested = false;
+ }
+
+ @Override
+ public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
+ Log.debug("Interstitial Ad failed to load, errorCode: " + loadAdError.getCode());
+ isInterstitialAdLoaded = false;
+ isInterstitialAdRequested = false;
+ }
+ });
// interstitialAdインスタンスにAdLisnerをセットしている部分 全部削除
- interstitialAd.setAdListener(new AdListener() {
- @Override
- public void onAdFailedToLoad(int errorCode) {
- Log.debug("Interstitial Ad failed to load, errocode: " + errorCode);
- isInterstitialAdLoaded = false;
- isInterstitialAdRequested = false;
- }
-
- @Override
- public void onAdLoaded() {
- //track if the ad is loaded since we can only called interstitialAd.isLoaded() from the uiThread
- isInterstitialAdLoaded = true;
- isInterstitialAdRequested = false;
- }
-});
参考
エラーの対処については以下のフォーラムが参考になりました。
コードの修正については、AdmobSDKのリファレンスやGitHubページが参考になりました。
修正後のAndroidAdvertising_APL.xml
Discussion