はじめに
最近SimpleChatGPTというアプリを開発して、GooglePlayにアップロードしました。それに関する記事が14,000PVに到達し、好評だったので広告の実装方法も紹介してみたいと思います。
ソースコードと解説
広告を初期化するAdsInitializer.csとInterstitialAdExapmles.csからなります。スクリプトは大体Unity公式ページのこことここを見れば初期化とロード方法がわかると思います。
この二つのスクリプトは空のゲームオブジェクトにくっつけて動作するようになっています。
わかりにくいですが_androidGameIdやInterstitial_AndroidなどはUnityダッシュボード->Monetization -> AdUnitsのところに載っているのでUnityのインスペクターにコピペして使ってあげてください!
InterstitialAdExample.csのUpdate関数が実際に広告を呼ぶ箇所です。始めはt = 0.1fですが、3fになった時点で一度起動時の広告を呼び、以後5分おきくらいに広告が流れます!t = 0fにすると2回広告が流れてしまいます!
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}");
}
}
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より大きい値になるまで広告をロードし続けたためと思われます。既にアップデートで修正済みです!