Unityで広告実装！

# はじめに
最近[SimpleChatGPT](https://play.google.com/store/apps/details?id=com.SixteenBitCompany.SimpleChatGPT)というアプリを開発して、GooglePlayにアップロードしました。[それに関する記事](https://qiita.com/gakusei_programmer/items/59d7278d49b68b2d6b9e)が14,000PVに到達し、好評だったので広告の実装方法も紹介してみたいと思います。

# ソースコードと解説
広告を初期化するAdsInitializer.csとInterstitialAdExapmles.csからなります。スクリプトは大体Unity公式ページの[ここ](https://docs.unity.com/ads/ja/manual/ImplementingBasicAdsUnity)と[ここ](https://docs.unity.com/ads/ja/manual/ImplementingRewardedAdsUnity)を見れば初期化とロード方法がわかると思います。
この二つのスクリプトは空のゲームオブジェクトにくっつけて動作するようになっています。
わかりにくいですが_androidGameIdやInterstitial_AndroidなどはUnityダッシュボード->Monetization -> AdUnitsのところに載っているのでUnityのインスペクターにコピペして使ってあげてください！
InterstitialAdExample.csのUpdate関数が実際に広告を呼ぶ箇所です。始めはt = 0.1fですが、3fになった時点で一度起動時の広告を呼び、以後5分おきくらいに広告が流れます！t = 0fにすると2回広告が流れてしまいます！
```AdInitializer.cs
using UnityEngine;
using UnityEngine.Advertisements;
using TMPro;
//広告を初期化するスクリプト
public class AdsInitializer : MonoBehaviour, IUnityAdsInitializationListener
{
    [SerializeField] string _androidGameId;
    [SerializeField] string _iOSGameId;
    [SerializeField] bool _testMode = true;
    private string _gameId;
    [SerializeField] TextMeshProUGUI ErrorMessage;
    void Awake()
    {
        
        if (Application.internetReachability == NetworkReachability.NotReachable)
        {
            ErrorMessage.text = "ネットワークエラー<br>再起動してください";
            Debug.Log("ネットワークエラー");
        }else{
            InitializeAds();
        }
    }
 
    public void InitializeAds()
    {
    #if UNITY_IOS
            _gameId = _iOSGameId;
    #elif UNITY_ANDROID
            _gameId = _androidGameId;
    #elif UNITY_EDITOR
            _gameId = _androidGameId; //Only for testing the functionality in the Editor
    #endif
        if (!Advertisement.isInitialized && Advertisement.isSupported)
        {
            Advertisement.Initialize(_gameId, _testMode, this);
        }
    }

 
    public void OnInitializationComplete()
    {
        Debug.Log("Unity Ads initialization complete.");
    }
 
    public void OnInitializationFailed(UnityAdsInitializationError error, string message)
    {
        Debug.Log($"Unity Ads Initialization Failed: {error.ToString()} - {message}");
    }



}

```

```InterstitialAdExample.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Advertisements;

//実際に広告を表示するスクリプト
public class InterstitialAdExample : MonoBehaviour, IUnityAdsLoadListener, IUnityAdsShowListener
{
    [SerializeField] string _androidAdUnitId = "Interstitial_Android";
    [SerializeField] string _iOsAdUnitId = "Interstitial_iOS";
    string _adUnitId;
 
    void Awake()
    {
        // Get the Ad Unit ID for the current platform:
        _adUnitId = (Application.platform == RuntimePlatform.IPhonePlayer)
            ? _iOsAdUnitId
            : _androidAdUnitId;
    }
 
    // Load content to the Ad Unit:
    public void LoadAd()
    {
        // IMPORTANT! Only load content AFTER initialization (in this example, initialization is handled in a different script).
        Debug.Log("Loading Ad: " + _adUnitId);
        Advertisement.Load(_adUnitId, this);
    }
 
    // Show the loaded content in the Ad Unit:
    public void ShowAd()
    {
        // Note that if the ad content wasn't previously loaded, this method will fail
        Debug.Log("Showing Ad: " + _adUnitId);
        Advertisement.Show(_adUnitId, this);
        //Advertisement.Banner.SetPosition(BannerPosition.TOP_CENTER);
        //Advertisement.Banner.Show(_adUnitId);
    }
 
    // Implement Load Listener and Show Listener interface methods: 
    public void OnUnityAdsAdLoaded(string adUnitId)
    {
        // Optionally execute code if the Ad Unit successfully loads content.
        ShowAd();
    }
 
    public void OnUnityAdsFailedToLoad(string _adUnitId, UnityAdsLoadError error, string message)
    {
        Debug.Log($"Error loading Ad Unit: {_adUnitId} - {error.ToString()} - {message}");
        // Optionally execute code if the Ad Unit fails to load, such as attempting to try again.
    }
 
    public void OnUnityAdsShowFailure(string _adUnitId, UnityAdsShowError error, string message)
    {
        Debug.Log($"Error showing Ad Unit {_adUnitId}: {error.ToString()} - {message}");
        // Optionally execute code if the Ad Unit fails to show, such as loading another ad.
    }
 
    public void OnUnityAdsShowStart(string _adUnitId) { }
    public void OnUnityAdsShowClick(string _adUnitId) { }
    public void OnUnityAdsShowComplete(string _adUnitId, UnityAdsShowCompletionState showCompletionState) { }
    
    float t = 0.1f;
    bool first_ad = true;
    void Update(){
        
       
        if(t ==0f){
            LoadAd();
        }

        t  += Time.deltaTime;//300秒おきに広告が流れる


        if(t > 300f)t = 0f;
        
        if(t>3f && first_ad){
            Debug.Log("FIRST_AD");
            LoadAd();
            first_ad = false;
        }
    }

   
    
   

}
    

```

# どうして3秒待ってから広告をロードするか
AdInitializer.csとInterstitialAdExample.csのAwake()関数の処理が一通り終了するのを待つためです。もっと綺麗な実装がありそうですが、思いつかなかったのでこのようにしてあります。

# 余談
初期のバージョンでは
```
if(t ==0f){
       LoadAd();
}
```
の箇所を、1フレームだけだと処理を見逃す可能性があると考えてif((int)t == 0)みたいに実装していました。実機テストでは思った通りに動作していたのですが、レビューを見ると広告が無限に繰り返されることがあるというクレームがありました。初期バージョンをダウンロードされた方、申し訳ありません。おそらく不動小数tが1より大きい値になるまで広告をロードし続けたためと思われます。**既にアップデートで修正済みです！**