Skip to content

Instantly share code, notes, and snippets.

@sathyarajshetigar
Created September 10, 2020 07:43
Show Gist options
  • Save sathyarajshetigar/b68053e5e9f64e694d17a0e45becf6a5 to your computer and use it in GitHub Desktop.
Save sathyarajshetigar/b68053e5e9f64e694d17a0e45becf6a5 to your computer and use it in GitHub Desktop.
#pragma warning disable CS0162, CS0612, CS0649, CS0618 // Type or member is obsolete
#define USE_UNITY_ADS
using UnityEngine;
using GoogleMobileAds.Api;
using System;
using System.Collections;
#if USE_UNITY_ADS
using UnityEngine.Advertisements;
#endif
public sealed class AdsManager : MonoBehaviour
#if USE_UNITY_ADS
, IUnityAdsListener
#endif
{
internal static AdsManager instance;
internal delegate void RewardAdLoaded(bool succes);
internal static RewardAdLoaded onRewardAdLoadedEvent;
public delegate void RewardAdCallback(bool completed, int amount);
private static RewardAdCallback _rewardAdCallback;
internal bool showingBannerAd => _showingBannerAd;
private InterstitialAd _interstitial;
private InterstitialAd _exitInterstitialAndroid;
private BannerView _bannerView;
private RewardBasedVideoAd _rewardBasedVideo;
private bool _rewardBasedEventHandlersSet;
private bool _didInitializeAdsManager;
private WaitForSeconds _unityBannerWait = new WaitForSeconds(0.5f);
private bool _admobBannerLoaded = false;
private bool _showingBannerAd;
[SerializeField]
private bool _adsEnabled = true;
[SerializeField]
private bool _useTestAds;
[SerializeField]
private bool _useAdaptiveAds;
[SerializeField]
private bool _useBannerAd;
[SerializeField]
private int _admobBannerPriority;
[SerializeField]
private bool _useInterstitialAd;
[SerializeField]
private int _admobPriority;
[SerializeField]
private int _rewardAmount;
[SerializeField]
private string _androidAppID;
[SerializeField]
private string _androidBannerID;
[SerializeField]
private string _androidInterstitialID;
[SerializeField]
private string _androidExitInterstitialID;
[SerializeField]
private string _androidRewardID;
[SerializeField]
private string _androidNativeAdID;
[Space(40)]
[SerializeField]
private string _iosAppID;
[SerializeField]
private string _iosBannerID;
[SerializeField]
private string _iosInterstitialID;
[SerializeField]
private string _iosRewardID;
[SerializeField]
private string _iosNativeAdID;
[Space(40)]
[SerializeField]
private string _iosUnityID;
[SerializeField]
private string _androidUnityID;
//Android Test Ad IDS
private const string ANDROIDBANNERIDTEST = "ca-app-pub-3940256099942544/6300978111";
private const string ANDROIDINTERSTITIALIDTEST = "ca-app-pub-3940256099942544/1033173712";
private const string ANDROIDREWARDIDTEST = "ca-app-pub-3940256099942544/5224354917";
private const string ANDROIDNATIVEADIDTEST = "ca-app-pub-3940256099942544/2247696110";
//ios Test Ad IDS
private const string IOSBANNERIDTEST = "ca-app-pub-3940256099942544/2934735716";
private const string IOSINTERSTITIALIDTEST = "ca-app-pub-3940256099942544/4411468910";
private const string IOSREWARDIDTEST = "ca-app-pub-3940256099942544/1712485313";
private const string IOSNATIVEADIDTEST = "ca-app-pub-3940256099942544/3986624511";
//Unity Ad placements
private const string UNITYBANNER = "banner";
private const string UNITYVIDEO = "video";
private const string UNITYREWARDVIDEO = "rewardedVideo";
public bool rewardVideoReady => (_rewardBasedVideo?.IsLoaded() ?? false) || UnityRewardAdReady();
public bool interstitialAdReady
{
get
{
// Debug.Log($"interstitialAdReady {_interstitial?.IsLoaded() ?? false } UnityInterstitialAdReady {UnityInterstitialAdReady()}");
return ((_interstitial?.IsLoaded() ?? false) || UnityInterstitialAdReady());
}
}
public bool androidExitInterstitialAdReady
{
get
{
// Debug.Log($"androidExitInterstitialAdReady {_exitInterstitialAndroid?.IsLoaded() ?? false } UnityInterstitialAdReady {UnityInterstitialAdReady()}");
return ((_exitInterstitialAndroid?.IsLoaded() ?? false) || UnityInterstitialAdReady());
}
}
private void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(gameObject);
StartAdManager();
}
else if (instance != this)
{
Destroy(gameObject);
}
}
public void StartAdManager()
{
if (!_didInitializeAdsManager)
{
_didInitializeAdsManager = true;
#if UNITY_EDITOR
return;
#endif
Init();
RequestBanner();
StartCoroutine("RequestUnityBannerAd");
RequestInterstitial();
RequestAndroidExitInterstitial();
RequestRewardBasedVideo();
//RequestNativeAd();
}
}
private void Init()
{
#if UNITY_EDITOR
string appID = "unused";
string unityAppID = "unused";
#elif UNITY_ANDROID
string appID = _androidAppID;
string unityAppID = _androidUnityID;
#elif UNITY_IOS
string appID = _iosAppID;
string unityAppID = _iosUnityID;
#else
string appID = "unexpected_platform";
#endif
MobileAds.Initialize(appID);
MobileAds.SetiOSAppPauseOnBackground(true);
#if USE_UNITY_ADS
Advertisement.AddListener(this);
Advertisement.Initialize(unityAppID, _useTestAds);
InvokeRepeating("CheckForRewardAd", 1, 5);
#endif
}
private void OnDestroy()
{
#if USE_UNITY_ADS
Advertisement.RemoveListener(this);
#endif
}
internal void DestoyAllAds()
{
HideBanner();
_adsEnabled = false;
}
//calculate physical inches with pythagoras theorem
public static float DeviceDiagonalSizeInInches()
{
float screenWidth = Screen.width / Screen.dpi;
float screenHeight = Screen.height / Screen.dpi;
float diagonalInches = Mathf.Sqrt(Mathf.Pow(screenWidth, 2) + Mathf.Pow(screenHeight, 2));
Debug.Log($"Getting device inches: {diagonalInches}");
return diagonalInches;
}
private void RequestBanner()
{
if (!_adsEnabled) return;
if (_bannerView == null)
{
#if UNITY_EDITOR
string adUnitId = "unused";
#elif UNITY_ANDROID
string adUnitId = _useTestAds ? ANDROIDBANNERIDTEST : _androidBannerID;
#elif UNITY_IOS
string adUnitId = _useTestAds ? IOSBANNERIDTEST : _iosBannerID;
#else
string adUnitId = "unexpected_platform";
#endif
#if UNITY_ANDROID || UNITY_IOS
AdSize adSize = AdSize.Banner;
if (DeviceDiagonalSizeInInches() > 6.5f)
adSize = AdSize.IABBanner; // Tablets
else
adSize = AdSize.SmartBanner; //Phones
//Use adaptive banner only in portrait mode
if (_useAdaptiveAds && (Screen.orientation == ScreenOrientation.Portrait || Screen.orientation == ScreenOrientation.PortraitUpsideDown))
{
// Calculates the width of the screen (safe area where available) in points.
float widthInPixels = Screen.safeArea.width > 0 ? Screen.safeArea.width : Screen.width;
int width = (int)(widthInPixels / MobileAds.Utils.GetDeviceScale());
adSize = AdSize.GetCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(width);
}
Debug.Log($"requesting width: {adSize.Width} Height: {adSize.Height}");
// Create an empty ad request.
AdRequest request;
if (_useTestAds)
{
Debug.Log($"Building Test ads");
request = new AdRequest.Builder()
.AddTestDevice(AdRequest.TestDeviceSimulator) // Simulator.
.AddTestDevice(SystemInfo.deviceUniqueIdentifier) // My test device.
.Build();
}
else
{
Debug.Log($"Building Real ads");
request = new AdRequest.Builder().Build();
}
// Create a banner at the top of the screen.
_bannerView = new BannerView(adUnitId, adSize, AdPosition.Bottom);
// Load the banner with the request.
_bannerView.LoadAd(request);
_bannerView.Show();
_bannerView.OnAdFailedToLoad += OnBannerAdFailedToLoadEvent;
_bannerView.OnAdLoaded += OnBannerAdLoadedEvent;
#endif
}
}
private void OnBannerAdFailedToLoadEvent(object sender, AdFailedToLoadEventArgs e)
{
_admobBannerLoaded = false;
Debug.Log($"OnBannerAdFailedToLoadEvent {e.Message}");
}
private void OnBannerAdLoadedEvent(object sender, EventArgs e)
{
_admobBannerLoaded = true;
}
public void ShowBanner()
{
if (!_adsEnabled) return;
if (!_useBannerAd) return;
#if UNITY_ANDROID || UNITY_IOS
#if USE_UNITY_ADS
Debug.Log($"ShowBanner admobBannerLoaded: {_admobBannerLoaded} UnityLoaded: {Advertisement.Banner.isLoaded} admobPriority: {_admobBannerPriority}");
#endif
_showingBannerAd = true;
if (_admobBannerPriority == 1)//Show Admob Banner Ads
{
if (_admobBannerLoaded)
{
_bannerView?.Show();
HideUnityBannerAd();//safe run
}
else
{
_bannerView?.Hide();//safe run
ShowUnityBannerAd();
}
}
else//Show Unity banner ads
{
#if USE_UNITY_ADS
if (Advertisement.Banner.isLoaded)
{
ShowUnityBannerAd();
_bannerView?.Hide();//safe run
}
else
#endif
{
if (_admobBannerLoaded)
_bannerView?.Show();
HideUnityBannerAd();//safe run
}
}
#endif
}
public void HideBanner()
{
if (!_adsEnabled) return;
#if UNITY_ANDROID || UNITY_IOS
// Debug.Log("HideBanner");
_bannerView?.Hide();
HideUnityBannerAd();
_showingBannerAd = false;
#endif
}
private void RequestInterstitial()
{
if (!_adsEnabled) return;
#if UNITY_ANDROID
string adUnitId = _useTestAds ? ANDROIDINTERSTITIALIDTEST : _androidInterstitialID;
#elif UNITY_IOS
string adUnitId = _useTestAds ? IOSINTERSTITIALIDTEST : _iosInterstitialID;
#else
string adUnitId = "unexpected_platform";
#endif
#if UNITY_ANDROID || UNITY_IOS
// Initialize an InterstitialAd.
_interstitial = new InterstitialAd(adUnitId);
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the interstitial with the request.
_interstitial.LoadAd(request);
_interstitial.OnAdFailedToLoad += OnInterstitialFailedLoad;
_interstitial.OnAdClosed += OnInterstitialAdClosed;
#endif
}
private void OnInterstitialFailedLoad(object sender, AdFailedToLoadEventArgs e)
{
Debug.Log($"OnInterstitialFailedLoad {e.Message}");
}
private void RequestAndroidExitInterstitial()
{
if (!_adsEnabled) return;
if (!_useInterstitialAd) return;
#if UNITY_ANDROID
string adUnitId = _useTestAds ? ANDROIDINTERSTITIALIDTEST : _androidExitInterstitialID;
#endif
#if UNITY_ANDROID
// Initialize an InterstitialAd.
_exitInterstitialAndroid = new InterstitialAd(adUnitId);
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the interstitial with the request.
_exitInterstitialAndroid.LoadAd(request);
#endif
}
public void ShowAndroidExitInterstitial()
{
if (!_adsEnabled) return;
Debug.Log($"exitInterstitialAndroid loaded: {_exitInterstitialAndroid?.IsLoaded()}");
Debug.Log($"UnityInterstitialAdReady : {UnityInterstitialAdReady()}");
#if UNITY_ANDROID
if (Game.admobPriority == 1 && (_exitInterstitialAndroid?.IsLoaded() ?? false))
_exitInterstitialAndroid?.Show();
else if (Game.admobPriority == 0 && UnityInterstitialAdReady())
ShowUnityInterstitial();
else
{
if (_interstitial?.IsLoaded() ?? false)
_interstitial?.Show();
else
ShowUnityInterstitial();
}
#endif
}
private void OnInterstitialAdClosed(object sender, EventArgs e)
{
RequestInterstitial();
}
//https://developers.google.com/admob/unity/native-express
private void RequestNativeAd()
{
if (!_adsEnabled) return;
#if UNITY_ANDROID
string adUnitId = _useTestAds ? ANDROIDNATIVEADIDTEST : _androidNativeAdID;
#elif UNITY_IOS
string adUnitId = _useTestAds ? IOSNATIVEADIDTEST : _iosNativeAdID;
#else
string adUnitId = "unexpected_platform";
#endif
#if UNITY_ANDROID || UNITY_IOS
//implement native
#endif
}
private void RequestRewardBasedVideo()
{
if (!_adsEnabled) return;
#if UNITY_EDITOR
string adUnitId = "unused";
#elif UNITY_ANDROID
string adUnitId = _useTestAds ? ANDROIDREWARDIDTEST : _androidRewardID;
#elif UNITY_IPHONE
string adUnitId = _useTestAds ? IOSREWARDIDTEST : _iosRewardID;
#else
string adUnitId = "unexpected_platform";
#endif
#if UNITY_ANDROID || UNITY_IOS
_rewardBasedVideo = RewardBasedVideoAd.Instance;
AdRequest request = new AdRequest.Builder().Build();
_rewardBasedVideo.LoadAd(request, adUnitId);
if (!_rewardBasedEventHandlersSet)
{
// Ad event fired when the rewarded video ad
// has been received.
_rewardBasedVideo.OnAdLoaded += HandleRewardBasedVideoLoaded;
// has failed to load.
_rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad;
// has rewarded the user.
_rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
_rewardBasedVideo.OnAdClosed += HandleRewardBasedAdClosed;
_rewardBasedEventHandlersSet = true;
}
#endif
}
public void ShowInterstitial(bool forceLoadUnityAd = false)
{
#if UNITY_ANDROID || UNITY_IOS
if (!_adsEnabled) return;
if (!_useInterstitialAd) return;
if (forceLoadUnityAd)
{
ShowUnityInterstitial();
return;
}
Debug.Log($"admob Interstitial loaded {_interstitial?.IsLoaded()}");
Debug.Log($"UnityInterstitialAdReady {UnityInterstitialAdReady()}");
if (_admobPriority == 1 && (_interstitial?.IsLoaded() ?? false))
_interstitial?.Show();
else if (_admobPriority == 0 && UnityInterstitialAdReady())
ShowUnityInterstitial();
else
{
if (_interstitial?.IsLoaded() ?? false)
_interstitial?.Show();
else
ShowUnityInterstitial();
}
#endif
}
public void ShowNativeAd()
{
#if UNITY_ANDROID || UNITY_IOS
if (!_adsEnabled) return;
#endif
}
public void HideNativeAd()
{
#if UNITY_ANDROID || UNITY_IOS
if (!_adsEnabled) return;
#endif
}
public void ShowRewardVideo(RewardAdCallback callback)
{
#if UNITY_ANDROID || UNITY_IOS
if (!_adsEnabled) return;
_rewardAdCallback = callback;
Debug.Log($"Show ShowRewardVideo rewardBasedVideo.IsLoaded {_rewardBasedVideo?.IsLoaded()}");
Debug.Log($"Unity Reward Ready ? {UnityRewardAdReady()}");
Debug.Log($"Game.admobPriority ? {_admobPriority}");
if (_admobPriority == 1 && (_rewardBasedVideo?.IsLoaded() ?? false))
_rewardBasedVideo?.Show();
else if (_admobPriority == 0 && UnityRewardAdReady())
ShowUnityReward();
else
{
if (_rewardBasedVideo?.IsLoaded() ?? false)
_rewardBasedVideo?.Show();
else if (UnityRewardAdReady())
ShowUnityReward();
else
onRewardAdLoadedEvent?.Invoke(false);
}
#endif
}
private void HandleRewardBasedVideoLoaded(object sender, EventArgs e)
{
Debug.Log("HandleRewardBasedVideoLoaded");
onRewardAdLoadedEvent?.Invoke(_rewardBasedVideo.IsLoaded());
}
private void HandleRewardBasedVideoFailedToLoad(object sender, AdFailedToLoadEventArgs e)
{
Debug.Log("HandleRewardBasedVideoFailedToLoad");
onRewardAdLoadedEvent?.Invoke(_rewardBasedVideo.IsLoaded());
}
private void HandleRewardBasedVideoRewarded(object sender, GoogleMobileAds.Api.Reward args)
{
Debug.Log("HandleRewardBasedVideoRewarded ");
this.InvokeDelayed(() =>
{
_rewardAdCallback?.Invoke(true, _rewardAmount);
_rewardAdCallback = null;
Invoke("ShowRewardDialog", 0.1f);
}, 0.5f);
}
private void HandleRewardBasedAdClosed(object sender, EventArgs e)
{
Debug.Log("HandleRewardBasedAdClosed ");
this.InvokeDelayed(() =>
{
_rewardAdCallback?.Invoke(false, 0);
_rewardAdCallback = null;
RequestRewardBasedVideo();
}, 0.5f);
}
private bool UnityRewardAdReady()
{
#if USE_UNITY_ADS
//Debug.Log($"UnityRewardAdReady IsReady ? {Advertisement.IsReady(UNITYREWARDVIDEO)}");
return Advertisement.IsReady(UNITYREWARDVIDEO);
#else
return false;
#endif
}
private bool UnityInterstitialAdReady()
{
#if USE_UNITY_ADS
//Debug.Log($"UnityInterstitialAdReady IsReady ? {Advertisement.IsReady(UNITYVIDEO)}");
return Advertisement.IsReady(UNITYVIDEO);
#else
return false;
#endif
}
private void CheckForRewardAd()
{
onRewardAdLoadedEvent?.Invoke(rewardVideoReady);
}
private void ShowUnityInterstitial()
{
#if USE_UNITY_ADS
if (UnityInterstitialAdReady())
{
Debug.Log("Showing Unity interstital ");
Advertisement.Show(UNITYVIDEO);
}
#endif
}
private void ShowUnityReward()
{
#if USE_UNITY_ADS
if (UnityRewardAdReady())
{
Debug.Log("Showing Unity Reward ");
Advertisement.Show(UNITYREWARDVIDEO);
}
#endif
}
private IEnumerator RequestUnityBannerAd()
{
#if USE_UNITY_ADS
while (!Advertisement.IsReady(UNITYBANNER))
yield return _unityBannerWait;
Debug.Log($"RequestUnityBannerAd isInitialized ? {Advertisement.isInitialized.ToString()}");
BannerLoadOptions bannerLoadOptions = new BannerLoadOptions();
bannerLoadOptions.errorCallback += (error) =>
{
//Debug.Log($"Unity Banner ad failed to load {error}");
// RequestUnityBannerAd();
};
bannerLoadOptions.loadCallback += () =>
{
//Debug.Log("Unity Banner ad loaded");
// ShowUnityBannerAd();
};
Advertisement.Banner.SetPosition(BannerPosition.BOTTOM_CENTER);
Advertisement.Banner.Load(UNITYBANNER, bannerLoadOptions);
#endif
yield return null;
}
private void ShowUnityBannerAd()
{
#if USE_UNITY_ADS
Advertisement.Banner.SetPosition(BannerPosition.BOTTOM_CENTER);
if (Advertisement.Banner.isLoaded)
Advertisement.Banner.Show(UNITYBANNER);
else
Debug.Log("Unity Banner ad failed to load");
#endif
}
private void HideUnityBannerAd()
{
#if USE_UNITY_ADS
Advertisement.Banner.Hide();
#endif
}
#if USE_UNITY_ADS
// Implement IUnityAdsListener interface methods:
public void OnUnityAdsDidFinish(string placementId, ShowResult showResult)
{
Debug.Log($"OnUnityAdsDidFinish--------------------------------------------------------------------------------showResult {showResult} placementId {placementId}");
// Define conditional logic for each ad completion status:
if (showResult == ShowResult.Finished)
{
// Reward the user for watching the ad to completion.
Debug.Log("The ad was successfully shown.");
this.InvokeDelayed(() =>
{
_rewardAdCallback?.Invoke(true, _rewardAmount);
_rewardAdCallback = null;
Invoke("ShowRewardDialog", 0.1f);
}, 0.5f);
}
else if (showResult == ShowResult.Skipped || showResult == ShowResult.Failed)
{
Debug.Log($"The ad failed to be shown. {showResult}");
this.InvokeDelayed(() =>
{
_rewardAdCallback?.Invoke(false, 0);
_rewardAdCallback = null;
}, 0.5f);
}
}
public void OnUnityAdsReady(string placementId)
{
// If the ready Placement is rewarded, show the ad:
Debug.Log($"OnUnityAdsReady------------------------------------------- {placementId}");
}
public void OnUnityAdsDidError(string message)
{
// Log the error.
Debug.LogError($"OnUnityAdsDidError------------------------------------------- {message}");
}
public void OnUnityAdsDidStart(string placementId)
{
// Optional actions to take when the end-users triggers an ad.
Debug.Log($"OnUnityAdsDidStart------------------------------------------- {placementId}");
}
#endif
void ShowRewardDialog()
{
if (Game.giveRewardCredits)
{
DialogBox.Show("Awesome", "You got " + _rewardAmount + " Free Credits.", "OK", delegate (bool ok) {
CurrencyManager.instance.AddCredits(_rewardAmount);
});
Game.giveRewardCredits = false;
}
else
{
DialogBox.Show("Congrats", "You will be rewarded with 2X credits when you win the next game", "OK", delegate (bool ok) { RewardCash(); });
}
}
private void RewardCash()
{
Game.giveRewardAdDoubleCredits = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment