1
0

【Unity】モバイルアプリに広告を実装する方法 (Google AdMob)

Last updated at Posted at 2024-08-11

まえがき

Unityで制作したモバイルアプリに広告を実装することで広告収入を得ることができるようになります。
ゲーム内で表示される広告には主に以下の3種類があります。

バナー広告
ゲーム中に画面下部など、画面の一部に表示される広告
インタースティシャル広告
画面の遷移時などに画面に大きく表示される広告
リワード広告
視聴することによってゲーム内で報酬を得ることが出来る広告

今回はこれらの広告の実装方法について説明していきます。

Google AdMobの登録

Google AdMobから自身のGoogleアカウントでログインして下さい。

すると、画面上部にこのような注意書きが表示されているので、修正ボタンを押して下さい。

スクリーンショット 2024-08-11 204410.png

指示に従って支払い情報と本人確認を済ませたら登録は完了です。

続いて、広告を実装したいアプリの登録をしていきます。

画面左側のアプリと書かれた項目からアプリの追加をクリックします。
指示に従ってアプリを登録することができたら、アプリの概要から広告ユニットの追加をしていきます。

スクリーンショット 2024-08-11 205949.png

広告ユニットを追加ボタンを押すと広告の種類が選べるので実装したい種類の広告を選択しましょう。

スクリーンショット 2024-08-11 205316.png

広告ユニット名を適当に決めて広告ユニットの作成ボタンを押せば完了です。他の実装したい広告に対しても同様に広告ユニットの作成を行って下さい。

GoogleMobileAdsパッケージの導入

Mobile Ads SDK からパッケージをインストールします。

少し下にスクロールすると次のような項目があるので、Import from GitHub をクリックして、1. Download ~ の中にある .unitypackage をクリックして下さい。

スクリーンショット 2024-08-11 210302.png

するとGitHubのページにリダイレクトされるので、一番上の GoogleMobileAds-vx.x.x.unitypackage (x.x.xの部分はバージョンによって変わります)をクリックしてパッケージのインストールを行って下さい。

スクリーンショット 2024-08-11 210554.png

UnityでProjectを開いた状態でインストールしたパッケージをダブルクリックするとImportできるので、Importを押してパッケージをインポートして下さい。

スクリーンショット 2024-08-11 211417.png

App IDの設定

Assets → Google Mobile Ads → Setting を選択して下さい。

スクリーンショット 2024-08-11 211514.png

するとInspectorが表示されるので、Google Mobile Ads App ID を設定します。

先ほどGoogle AdMobで追加したアプリのアプリIDを、アプリ一覧からコピーして入力、またはテスト用IDを入力します。AndroidまたはiOS一方のみ対応のアプリの場合は、片方だけ入力して下さい。

Androidテスト用AppID : ca-app-pub-3940256099942544~3347511713
iOSテスト用AppID : ca-app-pub-3940256099942544~1458002511

また、下3つのチェックボックスにすべてチェックを入れます。

スクリーンショット 2024-08-11 212216.png

Remote Configの設定

ストアにリリースする前の審査段階ではテスト広告の広告ユニットIDを使用していなければ広告が表示されないため、Google Admobで生成した広告ユニットIDを使用したまま審査に出してしまうとRejectされてしまいます。

しかし、審査が通った後に広告ユニットIDを差し替えて審査に出し直すと時間がかかってしまいます。

この問題を解決できるのがRemote Configで、Unity側で広告ユニットIDを差し替えるだけで実際に表示される広告も変動させることができます。

パッケージの導入

Unity側で Window → Package Manager を開きます。

スクリーンショット 2024-08-11 220524.png

画面上部の+マークの横にある項目から Packages: Unity Registry に切り替えて、Remoteと検索するとRemote Config というパッケージが出てくるので、Installボタンをクリックしてインストールします。

スクリーンショット 2024-08-11 225803.png

Unity Servicesの連携

Edit → Project Settings... を開きます。

スクリーンショット 2024-08-11 230809.png

初めてRemote Configの設定を行う場合は、ServicesからOrganizationの選択とprojectの選択を行い、Link Unity project to cloud project を選択してRefreshして下さい。

スクリーンショット 2024-08-11 231814.png

広告IDの設定

Window → Remote Configを選択します。

スクリーンショット 2024-08-11 232314.png

Add Settingから、使用したい広告に対応するkeyとvalueを設定します。keyの部分はkey_ad_(広告の種類)、TypeはString、valueは以下のテスト用広告IDを設定して下さい。

広告 key value
バナー広告 key_ad_banner ca-app-pub-3940256099942544/6300978111
リワード広告 key_ad_reward ca-app-pub-3940256099942544/5224354917
インタースティシャル広告 key_ad_interstitial ca-app-pub-3940256099942544/1033173712

スクリーンショット 2024-08-11 233422.png

最後にPushを押して、処理が完了するのを待ちましょう。

これでリリースする際にValueの部分を実際に使用する広告IDに書き換えることで、Remote Configから広告を差し替えることが可能になりました。

Scriptの追加

AdmobManagerというScriptを作成して、中身を下のコードに書き換えてください。

AdmobManager (クリックして表示)
using UnityEngine;
using GoogleMobileAds.Api;
using Unity.Services.Authentication;
using Unity.Services.Core;
using Unity.Services.RemoteConfig;

public class AdmobManager : MonoBehaviour
{
    public static AdmobManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType<AdmobManager>();
            }
            return instance;
        }
    }
    public static AdmobManager instance;

    private bool isReady = false;
    public bool IsReady
    {
        get
        {
            return isReady;
        }
    }

    [SerializeField] private bool useRemoteConfig = false;

    // Create attributes classes
    private class UserAttributes { }
    private class AppAttributes { }

    async void Start()
    {
        if (this != Instance)
        {
            Destroy(gameObject);
            return;
        }
        else
        {
            DontDestroyOnLoad(gameObject);
            instance = this;
        }

        if (useRemoteConfig)
        {
            if (Utilities.CheckForInternetConnection())
            {
                await UnityServices.InitializeAsync();

                if (!AuthenticationService.Instance.IsSignedIn)
                {
                    await AuthenticationService.Instance.SignInAnonymouslyAsync();
                }

                // Create instances of user and app attributes
                var userAttributes = new UserAttributes();
                var appAttributes = new AppAttributes();

                // Fetch Remote Config data
                await RemoteConfigService.Instance.FetchConfigsAsync(userAttributes, appAttributes);
            }
        }

        MobileAds.RaiseAdEventsOnUnityMainThread = true;
        MobileAds.Initialize(initStatus =>
        {
            isReady = true;
            Debug.Log(initStatus);
        });
    }
}

コード7行目の public class AdmobManager : MonoBehaviour の AdmobManagerの部分がScript名と一致している必要があるので、Script名が間違っていないか確認して下さい。他のScriptについても同様です。

続いて、 AdmobUnitBaseというScriptを作成して、中身を下のコードに書き換えて下さい。

AdmobUnitBase (クリックして表示)
using System.Collections;
using UnityEngine;
using GoogleMobileAds.Common;
using Unity.Services.RemoteConfig;

public abstract class AdmobUnitBase : MonoBehaviour
{
    [SerializeField] private string unitIDAndroid;
    [SerializeField] private string unitIDIOS;

    protected string UnitID
    {
        get
        {
#if UNITY_ANDROID
            return unitIDAndroid;
#elif UNITY_IOS
            return unitIDIOS;
#else
            return "";
#endif
        }
    }

    [Header("Remote Config")]
    [SerializeField] private bool useRemoteConfig = false;
    public bool UseRemoteConfig => useRemoteConfig;
    [SerializeField] private string keyUnitIDAndroid = "unit_id_android";
    [SerializeField] private string keyUnitIDIOS = "unit_id_ios";

    private void OnAppStateChangedBase(AppState state)
    {
        Debug.Log("App State changed to : " + state);
        OnAppStateChanged(state);
    }

    private IEnumerator Start()
    {
        while (AdmobManager.Instance.IsReady == false)
        {
            yield return 0;
        }
        if (useRemoteConfig)
        {
            unitIDAndroid = RemoteConfigService.Instance.appConfig.GetString(keyUnitIDAndroid);
            unitIDIOS = RemoteConfigService.Instance.appConfig.GetString(keyUnitIDIOS);
        }
        Initialize();
    }
    protected virtual void Initialize()
    {
        // Call after initialization of AdsManager
    }
    protected virtual void OnAppStateChanged(AppState state)
    {
    }
}

最後に、実装する広告に応じて、AdmobUnitBannerAdmobUnitRewardAdmobUnitInterstitialというScriptを作成して、それぞれの中身を下のコードに書き換えて下さい。

AdmobUnitBanner (クリックして表示)
using UnityEngine;
using GoogleMobileAds.Api;

public class AdmobUnitBanner : AdmobUnitBase
{
    private BannerView bannerView;

    protected override void Initialize()
    {
        ShowBanner();
    }

    public void ShowBanner()
    {
        if (bannerView != null)
        {
            Debug.Log("Destroying banner view.");
            bannerView.Destroy();
            bannerView = null;
        }

        // Create AdSize
        AdSize adaptiveSize = AdSize.GetCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(AdSize.FullWidth);

        // Designate AdSize as Argument
        bannerView = new BannerView(
            UnitID,
            adaptiveSize,
            AdPosition.Bottom);

        bannerView.OnBannerAdLoaded += () =>
        {
            Debug.Log("ロードされました - 表示します");
        };
        bannerView.OnBannerAdLoadFailed += (LoadAdError error) =>
        {
            Debug.LogError("ロード失敗しました");
        };

        // Generate Request
        var adRequest = new AdRequest();
        bannerView.LoadAd(adRequest);
    }

    private void UnitDestroy()
    {
        if (bannerView != null)
        {
            Debug.Log("Destroying banner view.");
            bannerView.Destroy();
            bannerView = null;
        }
    }

    private void OnDestroy()
    {
        UnitDestroy();
    }

}
AdmobUnitReward (クリックして表示)
using UnityEngine;
using GoogleMobileAds.Api;
using System;

public class AdmobUnitReward : AdmobUnitBase
{
    private RewardedAd rewardedAd;

    public bool IsReady
    {
        get
        {
            if (AdmobManager.Instance.IsReady == false)
            {
                return false;
            }
            return rewardedAd != null && rewardedAd.CanShowAd();
        }
    }
    protected override void Initialize()
    {
        LoadRewardAd();
    }

    public void LoadRewardAd()
    {
        if (IsReady)
        {
            Debug.Log("Reward ad is already loaded.");
            return;
        }

        // Clean up the old ad before loading a new one.
        if (rewardedAd != null)
        {
            rewardedAd.Destroy();
            rewardedAd = null;
        }

        var adRequest = new AdRequest();

        RewardedAd.Load(UnitID, adRequest,
            (RewardedAd ad, LoadAdError error) =>
            {
                if (error != null || ad == null)
                {
                    Debug.LogError("rewarded ad failed to load an ad " +
                        error?.ToString());
                    return;
                }

                rewardedAd = ad;
                RegisterEventHandlers(rewardedAd);
            });
    }

    public void ShowRewardAd(Action<Reward> onReward)
    {
        if (IsReady)
        {
            rewardedAd.Show((Reward reward) =>
            {
                Debug.Log("Reward ad completed successfully.");
                onReward?.Invoke(reward);
            });
        }
        else
        {
            Debug.Log("Reward ad is not ready yet.");
            onReward?.Invoke(null);
        }
    }

    private void RegisterEventHandlers(RewardedAd ad)
    {
        // Raised when the ad is estimated to have earned money.
        ad.OnAdPaid += (AdValue adValue) =>
        {
            Debug.Log(String.Format("Rewarded ad paid {0} {1}.",
                adValue.Value,
                adValue.CurrencyCode));
        };
        // Raised when an impression is recorded for an ad.
        ad.OnAdImpressionRecorded += () =>
        {
            Debug.Log("Rewarded ad recorded an impression.");
        };
        // Raised when a click is recorded for an ad.
        ad.OnAdClicked += () =>
        {
            Debug.Log("Rewarded ad was clicked.");
        };
        // Raised when an ad opened full screen content.
        ad.OnAdFullScreenContentOpened += () =>
        {
            Debug.Log("Rewarded ad full screen content opened.");
        };
        // Raised when the ad closed full screen content.
        ad.OnAdFullScreenContentClosed += () =>
        {
            Debug.Log("Rewarded ad full screen content closed.");
            LoadRewardAd();
        };
        // Raised when the ad failed to open full screen content.
        ad.OnAdFullScreenContentFailed += (AdError error) =>
        {
            Debug.LogError("Rewarded ad failed to open full screen content " +
                           "with error : " + error);
            LoadRewardAd();
        };
    }
}
AdmobUnitInterstitial (クリックして表示)
using UnityEngine;
using GoogleMobileAds.Api;
using System;
using UnityEngine.SceneManagement;

public class AdmobUnitInterstitial : AdmobUnitBase
{
    private InterstitialAd interstitialAd;
    private string nextSceneName;

    public bool IsReady
    {
        get
        {
            if (AdmobManager.Instance.IsReady == false)
            {
                return false;
            }
            return interstitialAd != null && interstitialAd.CanShowAd();
        }
    }

    protected override void Initialize()
    {
        LoadInterstitialAd();
    }

    public void ShowInterstitial(string sceneToLoad)
    {
        nextSceneName = sceneToLoad;
        if (IsReady)
        {
            interstitialAd.Show();
        }
        else
        {
            Debug.Log("Interstitial ad is not ready yet.");
            SceneManager.LoadScene(nextSceneName);  // Load scene immediately if ad is not ready
        }
    }

    private void LoadInterstitialAd()
    {
        // Clean up old ads before loading new ones
        if (interstitialAd != null)
        {
            interstitialAd.Destroy();
            interstitialAd = null;
        }

        var adRequest = new AdRequest();

        InterstitialAd.Load(UnitID, adRequest,
            (InterstitialAd ad, LoadAdError error) =>
            {
                if (error != null || ad == null)
                {
                    Debug.LogError("Interstitial ad failed to load an ad " +
                                   "with error : " + error);
                    return;
                }

                Debug.Log("Interstitial ad loaded with response : "
                          + ad.GetResponseInfo());

                interstitialAd = ad;
                RegisterEventHandlers(interstitialAd);
            });
    }

    private void RegisterEventHandlers(InterstitialAd interstitialAd)
    {
        // Called when the ad closes the full screen content
        interstitialAd.OnAdFullScreenContentClosed += () =>
        {
            Debug.Log("Interstitial ad full screen content closed.");
            LoadInterstitialAd();
            SceneManager.LoadScene(nextSceneName);  // Load scene after ads are closed.
        };
    }
}

また、リワード広告、インタースティシャル広告を使用する場合はTestRewardTestInterstitialというScriptも作成し、中身を下のコードに書き換えて下さい。

TestReward (クリックして表示)
using UnityEngine;
using UnityEngine.UI;

public class TestReward : MonoBehaviour
{
    public Button showRewardButton;

    public AdmobUnitReward admobUnitReward;

    private void Start()
    {
        showRewardButton.interactable = false;

        showRewardButton.onClick.AddListener(() =>
        {
            admobUnitReward.ShowRewardAd((reward) =>
            {
                if (reward != null)
                {
                    Debug.Log("Reward type: " + reward.Type);
                    Debug.Log("Reward received: " + reward.Amount);
                }
            });
            showRewardButton.interactable = false;
        });
    }

    private void Update()
    {
        showRewardButton.interactable = admobUnitReward.IsReady;
    }
}
TestInterstitial (クリックして表示)
using UnityEngine;
using UnityEngine.UI;

public class TestInterstitial : MonoBehaviour
{
    public Button showInterstitialButton;
    public AdmobUnitInterstitial admobUnitInterstitial;

    private void Start()
    {
        showInterstitialButton.interactable = true;

        showInterstitialButton.onClick.AddListener(() =>
        {
            string buttonTag = showInterstitialButton.tag;
            if (buttonTag == "retry")
            {
                admobUnitInterstitial.ShowInterstitial("game");
            }
            else if (buttonTag == "title")
            {
                admobUnitInterstitial.ShowInterstitial("title");
            }
            else
            {
                Debug.LogWarning("Button tag is not recognized.");
            }
            showInterstitialButton.interactable = true;
        });
    }

    private void Update()
    {
        showInterstitialButton.interactable = admobUnitInterstitial.IsReady;
    }
}

広告の表示

最後に、実際に広告を表示できるようにしていきましょう。

広告を表示したいSceneに移動して、AdmobManagerという空のオブジェクトを作成します。

これに、AdmobManager のScriptをアタッチして、Inspectorで Use Remote Config にチェックを入れます。

スクリーンショット 2024-08-12 004229.png

また、実装する広告に応じて、AdmobUnitBannerAdmobUnitRewardAdmobUnitInterstitialという空のオブジェクトを作成して、対応するScriptをアタッチして下さい。

Use Remote Configにチェックを入れ、下のKey Unit IDの部分に先ほどRemote Configで設定したvalueを広告の種類に応じて設定します。今回はAndroidのみ実装します。

スクリーンショット 2024-08-12 010952.png

他の種類の広告に対しても同様に操作して下さい。

バナー広告はこれで実際に表示されるようになります。Playを押してみて画面下部にバナーが表示されれば成功です。

リワード広告とインタースティシャル広告

リワード広告とインタースティシャル広告についてはボタンを押したら表示されるようにしたいので、追加の実装を行います。

実装する広告の種類に応じて、TestRewardTestInterstitialという名前の空のオブジェクトを作成します。

これに対応するScriptをアタッチして、Inspectorで設定を行います。

リワード広告の場合は広告を表示したら報酬がもらえるボタン、インタースティシャル広告は画面遷移を行うときのボタンのオブジェクトをShow Reward ButtonまたはShow Interstitial Buttonに設定して下さい。

Admob Unit RewardまたはAdmob Unit Interstitialの部分には対応するScriptを設定して下さい。

スクリーンショット 2024-08-12 013759.png

これでReward広告の実装は完了です。ボタンを押したら広告が表示されるのを確認しましょう。

実際に報酬が得られるようにするには、Google AdMobで作成したリワード広告の広告ユニットの設定から報酬の個数と報酬アイテムを設定しましょう。

インタースティシャル広告のボタン識別

また、インタースティシャル広告はボタンを識別して、広告がユーザーによって削除されたあとにそのボタンが押された処理を行うという実装になっているのでボタンを識別できるようにする必要があります。

TestInterstitialのScriptには、押されたボタンのTagが"retry"であれば"game"シーンをロード、押されたボタンのTagが"title"であれば"title"シーンをロードするようにしています。これは必要に応じて追加・編集して下さい。

TestInterstitialの一部
private void Start()
{
    showInterstitialButton.interactable = true;

    showInterstitialButton.onClick.AddListener(() =>
    {
        string buttonTag = showInterstitialButton.tag;
        if (buttonTag == "retry")
        {
            admobUnitInterstitial.ShowInterstitial("game");
        }
        else if (buttonTag == "title")
        {
            admobUnitInterstitial.ShowInterstitial("title");
        }
        else
        {
            Debug.LogWarning("Button tag is not recognized.");
        }
        showInterstitialButton.interactable = true;
    });
}

そのため、インタースティシャル広告を表示するボタンにTagをつければよいです。

ボタンのオブジェクトを選択し、Inspectorの上部からTagを設定することができます。Scriptで設定した"retry"や、"title"といったTagを作成し、それぞれのボタンに割り当てましょう。

スクリーンショット 2024-08-12 014703.png

実際にボタンを押してみて、広告を削除したら指定のシーンがロードされれば成功です。

以上でバナー広告、リワード広告、インタースティシャル広告の実装は完了です。お疲れ様でした。

あとがき

Google Admobを使用して広告の実装をしました。

審査が通ったらRemote Configのvalueをテスト広告IDから実際の広告ユニットIDに差し替えることをお忘れずに。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0