namespace GleyMobileAds { using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; #if USE_FACEBOOKADS using System.Linq; using AudienceNetwork; #endif public class CustomFacebook : MonoBehaviour, ICustomAds { #if USE_FACEBOOKADS && !UNITY_EDITOR private const float reloadTime = 30; private const int maxRetryCount = 10; private AdView bannerAd; private InterstitialAd interstitialAd; private RewardedVideoAd rewardedVideoAd; private UnityAction DisplayResult; private UnityAction OnInterstitialClosed; private UnityAction OnInterstitialClosedWithAdvertiser; private UnityAction OnCompleteMethod; private UnityAction OnCompleteMethodWithAdvertiser; private BannerPosition position; private BannerType bannerType; private string bannerId; private string interstitialId; private string rewardedVideoId; private int currentRetryInterstitial; private int currentRetryRewardedVideo; private bool debug; private bool initialized; private bool directedForChildren; private bool interstitialIsLoaded; private bool bannerUsed; private bool rewardedVideoisLoaded; private bool triggerCompleteMethod; #if UNITY_ANDROID private bool interstitialDidClose; private bool rewardedVideoDidClose; #endif /// /// Initializing Audience Network /// /// /// contains all required settings for this publisher public void InitializeAds(UserConsent consent, UserConsent ccpaConsent, List platformSettings) { debug = Advertisements.Instance.debug; if (initialized == false) { if (debug) { Debug.Log(this + " " + "Start Initialization"); ScreenWriter.Write(this + " " + "Start Initialization"); } //get settings #if UNITY_ANDROID PlatformSettings settings = platformSettings.First(cond => cond.platform == SupportedPlatforms.Android); #endif #if UNITY_IOS PlatformSettings settings = platformSettings.First(cond => cond.platform == SupportedPlatforms.iOS); if(consent == UserConsent.Accept|| consent == UserConsent.Unset) { AudienceNetwork.AdSettings.SetAdvertiserTrackingEnabled(true); } else { AudienceNetwork.AdSettings.SetAdvertiserTrackingEnabled(false); } #endif //apply settings interstitialId = settings.idInterstitial.id; bannerId = settings.idBanner.id; rewardedVideoId = settings.idRewarded.id; directedForChildren = settings.directedForChildren; //verify settings if (debug) { Debug.Log(this + " Banner ID: " + bannerId); ScreenWriter.Write(this + " Banner ID: " + bannerId); Debug.Log(this + " Interstitial ID: " + interstitialId); ScreenWriter.Write(this + " Interstitial ID: " + interstitialId); Debug.Log(this + " Rewarded Video ID: " + rewardedVideoId); ScreenWriter.Write(this + " Rewarded Video ID: " + rewardedVideoId); Debug.Log(this + " Directed for children: " + directedForChildren); ScreenWriter.Write(this + " Directed for children: " + directedForChildren); } AudienceNetwork.AdSettings.SetMixedAudience(directedForChildren); if (!string.IsNullOrEmpty(interstitialId)) { LoadInterstitial(); } if (!string.IsNullOrEmpty(rewardedVideoId)) { LoadRewardedVideo(); } initialized = true; } } /// /// This is not required for Facebook, Facebook consent is set using the Facebook app. /// /// public void UpdateConsent(UserConsent consent, UserConsent ccpaConsent) { #if UNITY_IOS if (consent == UserConsent.Accept || consent == UserConsent.Unset) { AudienceNetwork.AdSettings.SetAdvertiserTrackingEnabled(true); } else { AudienceNetwork.AdSettings.SetAdvertiserTrackingEnabled(false); } #endif } #region Interface Implementation - Banner /// /// Check if Facebook banner is available /// /// true if a banner is available public bool IsBannerAvailable() { return true; } /// /// Show Facebook banner /// /// can be TOP or BOTTOM /// /// can be Banner or SmartBanner public void ShowBanner(BannerPosition position, BannerType bannerType, UnityAction DisplayResult) { this.position = position; this.bannerType = bannerType; bannerUsed = true; this.DisplayResult = DisplayResult; LoadBanner(); } /// /// Hides Facebook banner /// public void HideBanner() { if (bannerAd) { bannerAd.Dispose(); } } /// /// Used for mediation purpose /// /// true if current banner failed to load public bool BannerAlreadyUsed() { return bannerUsed; } /// /// Used for mediation purpose /// public void ResetBannerUsage() { bannerUsed = false; } #endregion #region Interface Implementation - Interstitial /// /// Check if Facebook interstitial is available /// /// true if an interstitial is available public bool IsInterstitialAvailable() { return interstitialIsLoaded; } /// /// Show Facebook interstitial /// /// callback called when user closes interstitial public void ShowInterstitial(UnityAction InterstitialClosed) { if (IsInterstitialAvailable()) { OnInterstitialClosed = InterstitialClosed; interstitialAd.Show(); interstitialIsLoaded = false; } } /// /// Show Facebook interstitial /// /// callback called when user closes interstitial public void ShowInterstitial(UnityAction InterstitialClosed) { if (IsInterstitialAvailable()) { OnInterstitialClosedWithAdvertiser = InterstitialClosed; interstitialAd.Show(); } } #endregion #region Interface Implementation - Rewarded Video /// /// Check if Facebook rewarded video is available /// /// true if a rewarded video is available public bool IsRewardVideoAvailable() { return rewardedVideoisLoaded; } /// /// Show Facebook rewarded video /// /// callback called when user closes the rewarded video -> if true video was not skipped public void ShowRewardVideo(UnityAction CompleteMethod) { if (IsRewardVideoAvailable()) { rewardedVideoisLoaded = false; triggerCompleteMethod = true; OnCompleteMethod = CompleteMethod; rewardedVideoAd.Show(); } } /// /// Show Facebook rewarded video /// /// callback called when user closes the rewarded video -> if true video was not skipped. Also returns the ad provider public void ShowRewardVideo(UnityAction CompleteMethod) { rewardedVideoisLoaded = false; triggerCompleteMethod = true; OnCompleteMethodWithAdvertiser = CompleteMethod; rewardedVideoAd.Show(); } #endregion #region Banner Implementation /// /// Load a Facebook banner and ads the required listeners /// public void LoadBanner() { if (bannerAd) { bannerAd.Dispose(); } AdSize bannerSize; if (bannerType == BannerType.Banner) { bannerSize = AdSize.BANNER_HEIGHT_50; } else { bannerSize = AdSize.BANNER_HEIGHT_50; } bannerAd = new AdView(bannerId, bannerSize); bannerAd.Register(gameObject); // Set delegates to get notified on changes or when the user interacts with the ad. bannerAd.AdViewDidLoad += BannerLoadSucces; bannerAd.AdViewDidFailWithError = BannerLoadFailed; bannerAd.AdViewWillLogImpression = BannerAdWillLogImpression; bannerAd.AdViewDidClick = BannerAdDidClick; // Initiate a request to load an ad. bannerAd.LoadAd(); } /// /// Triggered when a Facebook banner is clicked /// private void BannerAdDidClick() { if (debug) { Debug.Log(this + " " + "Banner ad clicked."); ScreenWriter.Write(this + " " + "Banner ad clicked."); } } /// /// Triggered when a Facebook banner is displayed /// private void BannerAdWillLogImpression() { if (debug) { Debug.Log(this + " " + "Banner ad logged impression."); ScreenWriter.Write(this + " " + "Banner ad logged impression."); } } /// /// Triggered when banner failed to load /// /// the reason for fail private void BannerLoadFailed(string error) { if (debug) { Debug.Log(this + " " + "Banner Failed To Load " + error); ScreenWriter.Write(this + " " + "Banner Failed To Load " + error); } if (DisplayResult != null) { DisplayResult(false, position, bannerType); DisplayResult = null; } } /// /// Banner loaded and it will be displayed on screen /// private void BannerLoadSucces() { if (debug) { Debug.Log(this + " " + "Banner Loaded"); ScreenWriter.Write(this + " " + "Banner Loaded"); } if (position == BannerPosition.BOTTOM) { bannerAd.Show(AdPosition.BOTTOM); } else { bannerAd.Show(AdPosition.TOP); } if (DisplayResult != null) { DisplayResult(true, position, bannerType); DisplayResult = null; } } #endregion #region Interstitial Implementation /// /// Loads a Facebook interstitial and ads the required listeners /// private void LoadInterstitial() { if (interstitialAd != null) { interstitialAd.Dispose(); } interstitialIsLoaded = false; interstitialAd = new InterstitialAd(interstitialId); interstitialAd.Register(gameObject); interstitialAd.InterstitialAdDidLoad += InterstitialLoaded; interstitialAd.InterstitialAdDidFailWithError += InterstitialFailed; interstitialAd.InterstitialAdWillLogImpression += InterstitialAdWillLogImpression; interstitialAd.InterstitialAdDidClick += InterstitialAdDidClick; interstitialAd.InterstitialAdDidClose += InterstitialClosed; #if UNITY_ANDROID /* * Only relevant to Android. * This callback will only be triggered if the Interstitial activity has * been destroyed without being properly closed. This can happen if an * app with launchMode:singleTask (such as a Unity game) goes to * background and is then relaunched by tapping the icon. */ interstitialAd.interstitialAdActivityDestroyed = delegate () { if (!interstitialDidClose) { if (debug) { Debug.Log(this + " " + "Interstitial activity destroyed without being closed first."); ScreenWriter.Write(this + " " + "Interstitial activity destroyed without being closed first."); } InterstitialClosed(); } }; #endif interstitialAd.LoadAd(); } /// /// Triggered when an interstitial is clicked /// private void InterstitialAdDidClick() { if (debug) { Debug.Log(this + " " + "Interstitial ad clicked."); ScreenWriter.Write(this + " " + "Interstitial ad clicked."); } } /// /// Triggered when an interstitial is displayed /// private void InterstitialAdWillLogImpression() { if (debug) { Debug.Log(this + " " + "Interstitial ad logged impression."); ScreenWriter.Write(this + " " + "Interstitial ad logged impression."); } } /// /// Triggered when an interstitial is closed and loads another one /// private void InterstitialClosed() { if (debug) { Debug.Log(this + " " + "Reload Interstitial"); ScreenWriter.Write(this + " " + "Reload Interstitial"); } #if UNITY_ANDROID interstitialDidClose = true; #endif if (interstitialAd != null) { interstitialAd.Dispose(); } //reload interstitial LoadInterstitial(); //trigger complete event CompleteMethodInterstitial(); } /// /// Triggers the corresponding complete method /// private void CompleteMethodInterstitial() { if (OnInterstitialClosed != null) { OnInterstitialClosed(); OnInterstitialClosed = null; } if (OnInterstitialClosedWithAdvertiser != null) { OnInterstitialClosedWithAdvertiser(SupportedAdvertisers.Facebook.ToString()); OnInterstitialClosedWithAdvertiser = null; } } /// /// Triggered when interstitial failed to load. Reloads another one after the reload time passes /// /// the fail reason private void InterstitialFailed(string error) { if (debug) { Debug.Log(this + " " + "Interstitial Failed To Load: " + error); ScreenWriter.Write(this + " " + "Interstitial Failed To Load " + error); } //try again to load a rewarded video if (currentRetryInterstitial < maxRetryCount) { currentRetryInterstitial++; if (debug) { Debug.Log(this + " " + "RETRY " + currentRetryInterstitial); ScreenWriter.Write(this + " " + "RETRY " + currentRetryInterstitial); } Invoke("LoadInterstitial", reloadTime); } } /// /// Triggered when an interstitial is loaded and ready to be shown /// private void InterstitialLoaded() { if (interstitialAd.IsValid()) { interstitialIsLoaded = true; #if UNITY_ANDROID interstitialDidClose = false; #endif if (debug) { Debug.Log(this + " " + "Interstitial Loaded"); ScreenWriter.Write(this + " " + "Interstitial Loaded"); } currentRetryInterstitial = 0; } else { if (debug) { Debug.Log(this + " " + "Interstitial Loaded but is invalid"); ScreenWriter.Write(this + " " + "Interstitial Loaded but is invalid"); } //try again to load an interstitial video if (currentRetryInterstitial < maxRetryCount) { currentRetryInterstitial++; if (debug) { Debug.Log(this + " " + "RETRY " + currentRetryInterstitial); ScreenWriter.Write(this + " " + "RETRY " + currentRetryInterstitial); } Invoke("LoadInterstitial", reloadTime); } } } #endregion #region Rewarded Video /// /// Load a Facebook rewarded video and add the required listeners /// private void LoadRewardedVideo() { if (rewardedVideoAd != null) { rewardedVideoAd.Dispose(); } rewardedVideoAd = new RewardedVideoAd(rewardedVideoId); rewardedVideoAd.Register(gameObject); rewardedVideoAd.RewardedVideoAdDidLoad += RewardedVideoLoaded; rewardedVideoAd.RewardedVideoAdDidFailWithError += RewardedVideoFailed; rewardedVideoAd.RewardedVideoAdWillLogImpression += RewardedVideoAdWillLogImpression; rewardedVideoAd.RewardedVideoAdDidClick += RewardedVideoAdDidClick; rewardedVideoAd.RewardedVideoAdComplete += RewardedVideoWatched; rewardedVideoAd.RewardedVideoAdDidClose += RewardedVideoAdClosed; #if UNITY_ANDROID /* * Only relevant to Android. * This callback will only be triggered if the Rewarded Video activity * has been destroyed without being properly closed. This can happen if * an app with launchMode:singleTask (such as a Unity game) goes to * background and is then relaunched by tapping the icon. */ rewardedVideoAd.RewardedVideoAdActivityDestroyed = delegate () { if (!rewardedVideoDidClose) { Debug.Log("Rewarded video activity destroyed without being closed first."); Debug.Log("Game should resume. User should not get a reward."); RewardedVideoAdClosed(); } }; #endif rewardedVideoAd.LoadAd(); } /// /// Triggered when the rewarded video is closed. Load a new one /// private void RewardedVideoAdClosed() { #if UNITY_ANDROID rewardedVideoDidClose = true; #endif if (rewardedVideoAd != null) { rewardedVideoAd.Dispose(); } if (debug) { Debug.Log(this + " " + "OnAdClosed"); ScreenWriter.Write(this + " " + "OnAdClosed"); } //reload LoadRewardedVideo(); //if complete method was not already triggered, trigger complete method with ad skipped param if (triggerCompleteMethod == true) { CompleteMethodRewardedVideo(false); } } /// /// Triggered is the rewarded video was fully watched /// private void RewardedVideoWatched() { if (debug) { Debug.Log(this + " " + "Rewarded Video Watched"); ScreenWriter.Write(this + " " + "Rewarded Video Watched"); } triggerCompleteMethod = false; CompleteMethodRewardedVideo(true); } /// /// Trigger the required complete method /// /// private void CompleteMethodRewardedVideo(bool val) { if (OnCompleteMethod != null) { OnCompleteMethod(val); OnCompleteMethod = null; } if (OnCompleteMethodWithAdvertiser != null) { OnCompleteMethodWithAdvertiser(val, SupportedAdvertisers.Facebook.ToString()); OnCompleteMethodWithAdvertiser = null; } } /// /// Triggered when rewarded video is clicked /// private void RewardedVideoAdDidClick() { if (debug) { Debug.Log(this + " " + "Rewarded video ad clicked."); ScreenWriter.Write(this + " " + "Rewarded video ad clicked."); } } /// /// Triggered when rewarded video is shown /// private void RewardedVideoAdWillLogImpression() { if (debug) { Debug.Log(this + " " + "Rewarded video ad logged impression."); ScreenWriter.Write(this + " " + "Rewarded video ad logged impression."); } } /// /// Triggered when rewarded video failed to load. Try to load a new one after reload time /// /// the fail reason private void RewardedVideoFailed(string error) { if (debug) { Debug.Log(this + " " + "Rewarded Video Failed To Load: " + error); ScreenWriter.Write(this + " " + "Rewarded Video Failed To Load " + error); } //try again to load a rewarded video if (currentRetryRewardedVideo < maxRetryCount) { currentRetryRewardedVideo++; if (debug) { Debug.Log(this + " " + "RETRY " + currentRetryRewardedVideo); ScreenWriter.Write(this + " " + "RETRY " + currentRetryRewardedVideo); } Invoke("LoadRewardedVideo", reloadTime); } } /// /// Triggered when rewarded video was loaded and is ready to show /// private void RewardedVideoLoaded() { if (rewardedVideoAd.IsValid()) { if (debug) { Debug.Log(this + " " + "Rewarded Video Loaded"); ScreenWriter.Write(this + " " + "Rewarded Video Loaded"); } rewardedVideoisLoaded = true; #if UNITY_ANDROID rewardedVideoDidClose = false; #endif currentRetryRewardedVideo = 0; } else { if (debug) { Debug.Log(this + " " + "Rewarded Video Loaded but is invalid"); ScreenWriter.Write(this + " " + "Rewarded Video Loaded but is invalid"); } //try again to load a rewarded video if (currentRetryRewardedVideo < maxRetryCount) { currentRetryRewardedVideo++; if (debug) { Debug.Log(this + " " + "RETRY " + currentRetryRewardedVideo); ScreenWriter.Write(this + " " + "RETRY " + currentRetryRewardedVideo); } Invoke("LoadRewardedVideo", reloadTime); } } } #endregion private void OnApplicationFocus(bool focus) { if (focus == true) { if (IsInterstitialAvailable() == false) { if (currentRetryInterstitial == maxRetryCount) { LoadInterstitial(); } } if (IsRewardVideoAvailable() == false) { if (currentRetryRewardedVideo == maxRetryCount) { LoadRewardedVideo(); } } } } #else public bool BannerAlreadyUsed() { return false; } public void HideBanner() { } public void InitializeAds(UserConsent consent, UserConsent ccpaConsent, List platformSettings) { } public bool IsBannerAvailable() { return false; } public bool IsInterstitialAvailable() { return false; } public bool IsRewardVideoAvailable() { return false; } public void ResetBannerUsage() { } public void ShowBanner(BannerPosition position, BannerType bannerType, UnityAction DisplayResult) { } public void ShowInterstitial(UnityAction InterstitialClosed) { } public void ShowInterstitial(UnityAction InterstitialClosed) { } public void ShowRewardVideo(UnityAction CompleteMethod) { } public void ShowRewardVideo(UnityAction CompleteMethod) { } public void UpdateConsent(UserConsent consent, UserConsent ccpaConsent) { } #endif } }