Ragendom Ad Mediation
A lightweight, modular AdMob ad mediation system for Unity.
Prefer a Video Tutorial?
Skip the docs — follow along with our step-by-step YouTube video tutorial instead.
Enjoying this asset? Check out Ragendom's other assets on the Unity Asset Store!
Browse More Assets →Overview
Ragendom Ad Mediation provides a clean, production-ready abstraction layer for Google AdMob advertisements in Unity. It supports Banner, Interstitial, Rewarded Video, and App Open Ad formats, with built-in UMP/GDPR consent handling, iOS IDFA tracking, a no-ads purchase system, interstitial timing controls, and a fully functional Dummy provider for editor testing — all without requiring any external SDK to compile.
Key Features
- Zero dependencies at compile time — the project compiles and runs with the built-in Dummy provider. The Google Mobile Ads SDK is only required when building for a real device.
- Automatic SDK detection — when you import the Google Mobile Ads Unity Plugin, the
MODULE_ADMOBscripting define is added automatically. No manual setup required. - All ad formats — Banner, Interstitial, Rewarded Video, and App Open Ads.
- UMP/GDPR consent flow — built-in Google User Messaging Platform support with configurable debug geography.
- iOS IDFA tracking — App Tracking Transparency (ATT) dialog support.
- No-ads purchase support — a single method call disables banners and interstitials while keeping rewarded videos available.
- Interstitial timing system — configurable first-launch delay, per-session delay, and minimum cooldown between ads.
- Thread-safe callbacks — all ad SDK callbacks are marshalled to the Unity main thread automatically.
- Exponential retry — failed ad loads are retried with exponential backoff (up to 5 attempts).
- Assembly Definitions — proper .asmdef structure for fast compilation and Asset Store compliance.
Requirements
| Requirement | Details |
|---|---|
| Unity Version | 2021.3 LTS or newer (supports Unity 6000+) |
| Platforms | Android, iOS (Dummy provider works on all platforms including Editor) |
| TextMeshPro | Required Must be imported via the Package Manager or the TMP import prompt. See Quick Start step 1. |
| Active Input Handling | Required Must be set to "Both" in Edit > Project Settings > Player > Configuration > Active Input Handling. Required for UI button clicks to work. |
| Google Mobile Ads Unity Plugin | Optional Required only for real AdMob ads. v9.0.0 or newer recommended.
Download: github.com/googleads/googleads-mobile-unity |
| Unity iOS Support Package | Optional Required only for IDFA/ATT tracking on iOS. |
Project Structure
Documentation/
Documentation.html — This documentation
Core/
SimpleCallback.cs — Core delegate type
ISaveObject.cs — Save interface
Ragendom.Core.asmdef
Modules/
Defines/Scripts/
DefineAttribute.cs — Auto-detection attribute
Ragendom.Defines.asmdef
Editor/
DefineManager.cs — Auto-detect SDKs, manage defines
DefineManagerWindow.cs — Editor window UI
Ragendom.Defines.Editor.asmdef
Monetization/
MonetizationSettings.asset — Default settings asset
Scripts/
Monetization.cs — Static utility class
MonetizationSettings.cs — Root ScriptableObject settings
MonetizationInitModule.cs — Initialization component
Ragendom.Monetization.asmdef
Advertisement/
AdsManager.cs — Main static API
AdsSettings.cs — Ad-specific settings
AdProviderHandler.cs — Abstract provider base
LoadingTask.cs — Pre-init task system
UMPLoadingTask.cs — GDPR consent task
IDFALoadingTask.cs — iOS ATT task
AdsRewardsHolder.cs — Ready-made reward button
NoAdsReward.cs — No-ads purchase handler
AdSave.cs — Persistent ad state
Providers/AdMob/
AdMobHandler.cs — AdMob implementation
AdMobContainer.cs — AdMob config data
Providers/Dummy/
AdDummyHandler.cs — Dummy provider
AdDummyContainer.cs — Dummy config data
AdDummyController.cs — Dummy UI renderer
Editor/
AdsSettingsEditor.cs — Custom inspector
EditorAdsContainer.cs — Editor base class
EditorAdMobContainer.cs — AdMob inspector
EditorDummyContainer.cs — Dummy inspector
AdmobBuildHandler.cs — Pre-build App ID sync
Ragendom.Monetization.Ads.Editor.asmdef
Editor/
MonetizationSettingsEditor.cs
MonetizationInitModuleEditor.cs
MonetizationPlatformDetector.cs
WelcomePopup.cs — Welcome popup window
Ragendom.Monetization.Editor.asmdef
Examples/Ads Example/
Scenes/
Admob-Example.unity — Pre-built example scene
Scripts/
AdsManagerExampleScript.cs — Full API demo
Ragendom.Examples.asmdef
Editor/
AdsExampleSceneSetup.cs — Scene setup tool
Ragendom.Examples.Editor.asmdef
Quick Start (5 Minutes)
Get up and running with Dummy ads in the Unity Editor in 5 minutes.
Before using this asset, make sure the following two setup steps are completed:
Import TextMeshPro
This asset requires the TextMeshPro package. If you haven't imported it yet, go to Window > Package Manager, search for TextMeshPro, and click Install. Alternatively, Unity may prompt you to import TMP Essentials the first time a TMP component is used — accept that prompt.
Set Active Input Handling to "Both"
The UI buttons in the example scene (and any scene using this asset's UI components) require the legacy Input Manager to be active. Go to Edit > Project Settings > Player > Configuration > Active Input Handling and set it to "Both". This allows both the legacy Input Manager and the new Input System to work side by side, ensuring that button clicks in the scene are properly detected.
Changing this setting will cause Unity to restart the editor. Save your work before applying the change.
Create the MonetizationSettings Asset
Right-click in the Project window and select Create > Data > Core > Monetization Settings. This creates a MonetizationSettings.asset ScriptableObject. Place it anywhere you like (e.g. Assets/Settings/).
Add MonetizationInitModule to Your Scene
Create an empty GameObject in your first scene and name it Monetization. Add the MonetizationInitModule component to it. Drag your MonetizationSettings asset into the Settings field.
Configure Providers
Select the MonetizationSettings asset. In the Inspector, you will see the Ads Settings section. Set each ad type (Banner, Interstitial, Rewarded Video) to Dummy for editor testing. Enable Verbose Logging to see detailed logs in the Console.
Press Play
Hit Play. The system initializes automatically via MonetizationInitModule.Awake(). You can now call any AdsManager method from your scripts. The Dummy provider renders simulated ad overlays directly in the Game view.
You can open the included Admob-Example scene (located in Ragendom/Examples/Ads Example/Scenes/) for a ready-made test environment. Alternatively, use the menu item Tools > Ragendom > Setup Ads Example Scene to automatically set up a complete test scene with all buttons wired to every AdsManager method. This is great for verifying the system works before integrating into your own project.
Testing
Testing with Dummy Ads (Editor)
The Dummy provider lets you test the entire ad lifecycle without any external SDK. It works in the Unity Editor on any platform.
- In your
MonetizationSettingsasset, set all three provider slots (Banner, Interstitial, Rewarded Video) to Dummy. - Press Play in the Unity Editor.
- The console should show:
[UMP]: AdMob module not available, skipping UMP. [Monetization]: Loading task 'UMP Consent' completed with status: Skipped [AdsManager]: Dummy ad provider initialized. [AdsManager]: Dummy provider initialized successfully. [AdsManager]: First ads loaded. [AdsManager]: Module initialized. [AdsManager]: Provider initialized: Dummy - Call
AdsManager.ShowBanner()to see a simulated banner overlay at the bottom (or top) of the screen. - Call
AdsManager.RequestInterstitial()followed byAdsManager.ShowInterstitial(callback)to see a fullscreen simulated interstitial with a Close button. - Call
AdsManager.RequestRewardBasedVideo()followed byAdsManager.ShowRewardBasedVideo(callback)to see a simulated rewarded video with "Watch" and "Close" buttons.
Banner: Show/Hide/Destroy all work. Banner appears as a colored bar.
Interstitial: Check Loaded returns False before request, True after. Show displays overlay, callback returns true.
Rewarded Video: Same pattern. Clicking "Watch" grants the reward (callback(true)). Clicking "Close" does not (callback(false)).
After showing: The ad is consumed. Calling Show again without a new Request will correctly warn "not loaded yet".
Testing with Real AdMob Ads (On Device)
Follow these steps to test with actual Google AdMob test ads on a physical Android or iOS device.
Import Google Mobile Ads Unity Plugin
Download the latest .unitypackage from the
Google Mobile Ads Unity Plugin releases page.
In Unity, go to Assets > Import Package > Custom Package and select the downloaded file. Import all files.
Verify Automatic SDK Detection
After Unity finishes recompiling, open the Define Manager window at Window > Ragendom Core > Define Manager.
You should see MODULE_ADMOB listed and enabled (checked). This was detected automatically because the
type GoogleMobileAds.Api.MobileAds now exists in the project.
If it does not appear automatically, click the toggle to enable it manually. This adds the MODULE_ADMOB scripting define symbol to your Player Settings.
Configure Google Mobile Ads Settings
The Google plugin creates its own settings asset. Open it via Assets > Google Mobile Ads > Settings.
Enter your AdMob App ID for Android and/or iOS. The App ID format is ca-app-pub-XXXXXXXXXXXXXXXX~XXXXXXXXXX.
You can find or create this in the AdMob Console under Apps.
Switch Providers to AdMob
Select your MonetizationSettings asset. In the Inspector, change each provider from Dummy to AdMob:
- Banner Provider → AdMob
- Interstitial Provider → AdMob
- Rewarded Video Provider → AdMob
The ad unit IDs are already pre-filled with Google's official test ad unit IDs. Leave them as-is for testing.
Register Your Test Device
In the MonetizationSettings Inspector, find the Test Devices list and add your physical device's hashed ID.
To find your device ID:
- Build and run the app once on your device.
- Check the device logcat (Android) or Xcode console (iOS) for a line like:
Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("XXXXXXXX") - Copy that hash string and add it to the Test Devices list.
Build and Run on Device
Go to File > Build Settings. Switch to Android or iOS.
For Android, ensure the minimum API level is 21 or higher.
For iOS, you need Xcode and a valid Bundle Identifier.
Click Build and Run.
Test on Device
The app will show the same UI. Now the buttons trigger real AdMob test ads: banners, fullscreen interstitials, and rewarded videos will display with a "Test Ad" watermark. This confirms the SDK is working correctly with test ad unit IDs.
Never click your own real ads. Google will flag your account for invalid traffic and may permanently ban it. Always use test ad unit IDs during development. Only switch to production ad unit IDs when publishing.
Testing Checklist
| Test | Expected Result |
|---|---|
| Show Banner | Banner appears at configured position (top/bottom) |
| Hide Banner | Banner disappears but can be re-shown |
| Destroy Banner | Banner is fully removed, needs new load to show again |
| Check Interstitial (before request) | Returns false |
| Request Interstitial | Console shows "loaded" message |
| Check Interstitial (after request) | Returns true |
| Show Interstitial | Fullscreen ad appears, callback returns true on close |
| Check Rewarded (before request) | Returns false |
| Request Rewarded Video | Console shows "loaded" message |
| Check Rewarded (after request) | Returns true |
| Show Rewarded Video (watch fully) | Callback returns true (reward granted) |
| Show Rewarded Video (close early / not loaded) | Callback returns false (no reward) |
| Show again without re-requesting | Warning: "not loaded yet", callback false |
| DisableForcedAd() | Banner destroyed, interstitials blocked, rewarded still works |
Integration Guide
Setting Up in Your Project
Create MonetizationSettings Asset
Right-click in the Project window: Create > Data > Core > Monetization Settings. This creates a ScriptableObject with an embedded AdsSettings sub-asset.
Add MonetizationInitModule to Your First Scene
Create a GameObject in your startup scene. Add the MonetizationInitModule component. Assign your MonetizationSettings asset. The system initializes automatically in Awake().
Add Your Assembly Reference
If your scripts use Assembly Definitions, add Ragendom.Monetization to your .asmdef's references list. If you don't use Assembly Definitions, no action needed — the assemblies are set to autoReferenced: true.
Add the Namespace
Add using Ragendom; at the top of any script that calls AdsManager methods.
Banner Ads
using Ragendom;
// Show a banner ad
AdsManager.ShowBanner();
// Hide the banner (keeps it in memory for fast re-show)
AdsManager.HideBanner();
// Fully destroy the banner (frees memory, will reload on next ShowBanner)
AdsManager.DestroyBanner();
Banners are automatically hidden when the user purchases no-ads (DisableForcedAd()). You do not need to manually check for no-ads status before showing a banner — the system handles it.
Interstitial Ads
using Ragendom;
// Pre-load an interstitial (called automatically on init if loadAdsOnStart is true)
AdsManager.RequestInterstitial();
// Check if an interstitial is ready
bool ready = AdsManager.IsInterstitialLoaded();
// Show an interstitial with a result callback
AdsManager.ShowInterstitial((bool success) =>
{
if (success)
{
// Ad was shown and closed
Debug.Log("Interstitial completed");
}
else
{
// Ad could not be shown (not loaded, on cooldown, no-ads purchased, etc.)
Debug.Log("Interstitial not shown");
}
});
// Show interstitial ignoring cooldown timer and custom conditions
AdsManager.ShowInterstitial(callback, ignoreConditions: true);
Interstitials are automatically re-requested after being shown. The system enforces:
- First launch delay (
interstitialFirstStartDelay) — seconds before the first interstitial on first-ever app launch - Session delay (
interstitialStartDelay) — seconds before the first interstitial on subsequent launches - Cooldown (
interstitialShowingDelay) — minimum seconds between consecutive interstitials
Rewarded Video Ads
using Ragendom;
// Pre-load a rewarded video
AdsManager.RequestRewardBasedVideo();
// Check if a rewarded video is ready
bool ready = AdsManager.IsRewardBasedVideoLoaded();
// Show a rewarded video
AdsManager.ShowRewardBasedVideo((bool rewarded) =>
{
if (rewarded)
{
// User watched the full video - grant the reward!
GiveCoins(100);
}
else
{
// User closed early or ad failed to show
ShowMessage("Watch the full video to earn your reward.");
}
});
Rewarded videos are always available, even if the user has purchased no-ads. This is intentional — rewarded videos are opt-in and provide value to the user. Only banners and interstitials are disabled by the no-ads purchase.
Using the AdsRewardsHolder Component
For simple cases, you can use the pre-built AdsRewardsHolder component instead of writing code:
- Add
AdsRewardsHolderto any GameObject. - Assign a UI Button to the
rewardButtonfield. - Create a subclass overriding
ApplyReward()with your reward logic:
public class CoinRewardHolder : AdsRewardsHolder
{
protected override void ApplyReward()
{
// This is called only when the user earns the reward
PlayerData.AddCoins(100);
}
}
No-Ads / Remove Ads Purchase
// Call this when the user successfully purchases "Remove Ads" via IAP
AdsManager.DisableForcedAd();
// Check if the user has already purchased no-ads
bool hasPurchased = !AdsManager.IsForcedAdEnabled();
// Listen for the no-ads event
AdsManager.ForcedAdDisabled += () =>
{
// Hide the "Remove Ads" button
removeAdsButton.SetActive(false);
};
When DisableForcedAd() is called:
- The state is saved to
PlayerPrefs(persists across sessions) - Banners are immediately destroyed
- Interstitials will no longer show
- Rewarded videos remain available
- The
ForcedAdDisabledevent fires
Using the NoAdsReward Component
The pre-built NoAdsReward component simplifies the UI:
- Add
NoAdsRewardto any GameObject. - Assign your "Remove Ads" UI panel/button to the
noAdsOfferObjectfield. - Call
noAdsReward.ApplyReward()from your IAP purchase success callback. - The component automatically hides the offer UI when ads are disabled.
Custom Interstitial Conditions
You can add custom conditions that must be met before an interstitial will show:
// Add a condition: don't show interstitials during gameplay
AdsManager.InterstitialConditions += () => !GameManager.IsInGameplay;
// Add another condition: require at least 3 levels completed
AdsManager.InterstitialConditions += () => PlayerData.LevelsCompleted >= 3;
// All conditions must return true for the interstitial to show.
// Any single condition returning false blocks the ad.
// These conditions are skipped when ignoreConditions: true is passed.
Settings Reference
MonetizationSettings
The root settings asset. Created via Create > Data > Core > Monetization Settings.
| Field | Type | Default | Description |
|---|---|---|---|
isModuleActive | bool | true | Global kill-switch. When false, all ad calls silently fail. |
verboseLogging | bool | false | Enables detailed [AdsManager] log messages in the Console. |
debugMode | bool | false | Exposes extra debug info in the custom inspector. |
testDevices | List<string> | empty | Hashed device IDs for AdMob test ads and UMP debug. |
privacyLink | string | "" | Your privacy policy URL (for use in consent UI). |
termsOfUseLink | string | "" | Your terms of use URL. |
AdsSettings
Embedded sub-asset inside MonetizationSettings. Contains all ad-specific configuration.
Provider Selection
| Field | Type | Default | Description |
|---|---|---|---|
bannerType | AdProvider | Dummy | Which provider serves banner ads. |
interstitialType | AdProvider | Dummy | Which provider serves interstitial ads. |
rewardedVideoType | AdProvider | Dummy | Which provider serves rewarded video ads. |
loadAdsOnStart | bool | true | Automatically request all ads after initialization completes. |
Interstitial Timing
| Field | Type | Default | Description |
|---|---|---|---|
interstitialFirstStartDelay | float | 40 | Seconds before the first interstitial can show on the very first app launch. |
interstitialStartDelay | float | 40 | Seconds before the first interstitial can show on subsequent launches. |
interstitialShowingDelay | float | 30 | Minimum seconds between consecutive interstitials. |
autoShowInterstitial | bool | false | When true, automatically shows interstitials whenever the cooldown expires. |
UMP / GDPR Consent
| Field | Type | Default | Description |
|---|---|---|---|
isUMPEnabled | bool | true | Run the UMP consent flow before initializing ads. |
umpTagForUnderAgeOfConsent | bool | false | Tag the request for users under the age of consent. |
umpDebugMode | bool | false | Enable UMP debug geography simulation. |
umpDebugGeography | DebugGeography | Disabled | Simulated geography: Disabled, EEA, or NotEEA. |
IDFA / iOS Tracking
| Field | Type | Default | Description |
|---|---|---|---|
isIDFAEnabled | bool | false | Show the iOS App Tracking Transparency dialog before ads init. |
trackingDescription | string | "Your data will be used..." | The description shown in the iOS ATT permission dialog. |
AdMob Configuration
These fields appear in the Inspector when you select the MonetizationSettings asset and have at least one provider set to AdMob.
App IDs
| Field | Platform | Default |
|---|---|---|
androidAppId | Android | Google test app ID |
iosAppId | iOS | Google test app ID |
Ad Unit IDs
| Ad Format | Android Default (Test) | iOS Default (Test) |
|---|---|---|
| Banner | ca-app-pub-3940256099942544/6300978111 | ca-app-pub-3940256099942544/2934735716 |
| Interstitial | ca-app-pub-3940256099942544/1033173712 | ca-app-pub-3940256099942544/4411468910 |
| Rewarded Video | ca-app-pub-3940256099942544/5224354917 | ca-app-pub-3940256099942544/1712485313 |
| App Open Ad | ca-app-pub-3940256099942544/9257395921 | ca-app-pub-3940256099942544/5575463023 |
The default IDs are Google's official test ad unit IDs. They are safe for development and will display ads with a "Test Ad" watermark. Replace them with your real ad unit IDs only when you are ready to publish. The inspector will show a warning if you are still using test IDs.
Banner Settings
| Field | Options | Description |
|---|---|---|
bannerType | Banner (320x50), MediumRectangle (300x250), IABBanner (468x60), Leaderboard (728x90) | Physical size of the banner. |
bannerPosition | Bottom, Top | Screen edge where the banner is anchored. |
App Open Ad Settings
| Field | Type | Default | Description |
|---|---|---|---|
useAppOpenAd | bool | false | Enable App Open Ads (shown when the app returns from background). |
appOpenAdExpirationHoursTime | int | 4 | Hours after which a loaded App Open Ad expires and will not be shown. |
API Reference
AdsManager (Static Class)
All ad operations go through this single static class. Add using Ragendom; to your script.
Initialization
| Method | Description |
|---|---|
Init(MonetizationSettings) | Called automatically by MonetizationInitModule.Awake(). Do not call manually unless you have a custom init flow. Calling more than once logs a warning. |
Banner
| Method | Description |
|---|---|
ShowBanner() | Shows the banner at the configured position. Respects no-ads state. |
HideBanner() | Hides the banner without destroying it. Fast to re-show. |
DestroyBanner() | Destroys the banner completely. Next ShowBanner() will reload it. |
EnableBanner() | Re-enables the banner flag and calls ShowBanner(). Used internally by App Open Ads. |
DisableBanner() | Disables the banner flag and calls HideBanner(). Used internally by App Open Ads. |
Interstitial
| Method | Description |
|---|---|
IsInterstitialLoaded() | Returns true if an interstitial is loaded and ready to show. |
RequestInterstitial() | Loads a new interstitial. Called automatically after showing one. |
ShowInterstitial(callback, ignoreConditions) | Shows the interstitial. callback(true) if shown, callback(false) if any guard fails. Pass ignoreConditions: true to skip timing and custom condition checks. |
CheckInterstitialTime() | Returns true if the cooldown timer has elapsed. |
ResetInterstitialDelayTime() | Resets the cooldown timer. Called automatically after showing ads. |
SetInterstitialDelayTime(float) | Manually sets the cooldown to a custom duration (seconds from now). |
Rewarded Video
| Method | Description |
|---|---|
IsRewardBasedVideoLoaded() | Returns true if a rewarded video is loaded and ready. Not affected by no-ads state. |
RequestRewardBasedVideo() | Loads a new rewarded video. Called automatically after showing one. |
ShowRewardBasedVideo(callback) | Shows the rewarded video. callback(true) if the user watched fully and earned the reward. callback(false) if the user closed early or the ad failed. |
No-Ads / Forced Ad Control
| Method | Description |
|---|---|
IsForcedAdEnabled() | Returns true if the user has NOT purchased no-ads. Banners and interstitials only show when this is true. |
DisableForcedAd() | Permanently disables banners and interstitials. Call this from your IAP success callback. Saves to PlayerPrefs. |
Events
Subscribe to these events to react to ad lifecycle changes:
// Fired when a provider finishes async initialization
AdsManager.AdProviderInitialized += (AdProvider provider) =>
{
Debug.Log($"Provider ready: {provider}");
};
// Fired when any ad finishes loading
AdsManager.AdLoaded += (AdProvider provider, AdType adType) =>
{
Debug.Log($"{adType} loaded from {provider}");
};
// Fired when any ad is displayed on screen
AdsManager.AdDisplayed += (AdProvider provider, AdType adType) =>
{
// Pause game audio, timers, etc.
};
// Fired when any ad is closed/dismissed
AdsManager.AdClosed += (AdProvider provider, AdType adType) =>
{
// Resume game audio, timers, etc.
};
// Fired when no-ads is purchased
AdsManager.ForcedAdDisabled += () =>
{
// Update UI: hide "Remove Ads" button
};
UMP / GDPR Consent
These methods wrap the Google User Messaging Platform (UMP) SDK for GDPR compliance. They only function when the AdMob SDK is present (MODULE_ADMOB defined). Without the SDK, they return safe defaults.
| Method | Returns | Description |
|---|---|---|
CanRequestAds() | bool | Whether UMP consent allows ad requests. Returns true without AdMob SDK. |
GetConsentStatus() | ConsentRequirementStatus | Current consent requirement: Unknown, Required, or NotRequired. Returns Unknown without SDK. |
ResetConsentState() | void | Clears all stored consent data. Useful for re-testing the UMP flow. No-op without SDK. |
IDFA Tracking (iOS)
These methods are only available when both conditions are met: the build target is iOS (UNITY_IOS) and the Unity iOS Support package is installed (MODULE_IDFA).
| Method | Returns | Description |
|---|---|---|
GetIDFAStatus() | AuthorizationTrackingStatus | NOT_DETERMINED, RESTRICTED, DENIED, or AUTHORIZED |
IsIDFADetermined() | bool | Returns true if the ATT dialog has been shown and the user responded. |
Advanced Topics
Automatic SDK Detection (Define System)
The system uses a custom [Define] attribute and an editor-time DefineManager to automatically detect installed SDKs and add the corresponding scripting define symbols.
The AdsManager class is decorated with:
[Define("MODULE_ADMOB", "GoogleMobileAds.Api.MobileAds")]
On every Unity domain reload (script compile, entering Play mode, etc.), the DefineManager:
- Scans all loaded assemblies for classes with
[Define]attributes. - For each attribute, checks if the target type (e.g.
GoogleMobileAds.Api.MobileAds) exists in any assembly. - If found: adds the define symbol (
MODULE_ADMOB) to Player Settings. - If not found: removes the define symbol.
This means:
- Importing the Google Mobile Ads Unity Plugin automatically enables
MODULE_ADMOB. - Removing the plugin automatically disables
MODULE_ADMOB. - You can view and manually toggle defines via
Window > Ragendom Core > Define Manager.
Thread Safety
Ad SDKs (especially AdMob) fire their callbacks on background threads, but Unity APIs can only be called from the main thread. The system handles this transparently:
- All ad callbacks in
AdMobHandleruseAdsManager.CallEventInMainThread()to enqueue actions. - The internal
AdEventExecutorMonoBehaviour flushes this queue everyUpdate(). - Your callbacks (e.g.
ShowInterstitial(callback)) are always called on the main thread — you can safely call Unity APIs from them.
Retry & Exponential Backoff
When an ad fails to load (network error, no fill, etc.), the system retries automatically:
| Attempt | Delay |
|---|---|
| 1st retry | 2 seconds |
| 2nd retry | 4 seconds |
| 3rd retry | 8 seconds |
| 4th retry | 16 seconds |
| 5th retry | 32 seconds |
| After 5th | Stops retrying. Next explicit Request*() call restarts the cycle. |
App Open Ads
App Open Ads are fullscreen ads shown when the user returns to your app from the background. To enable:
- In your
MonetizationSettings→ AdMob settings, check Use App Open Ad. - Set the Android and iOS App Open Ad unit IDs (or keep the defaults for testing).
- Set the Expiration Hours (default: 4). A loaded ad older than this will not be shown.
Behavior:
- An App Open Ad is loaded at initialization and re-loaded after each display.
- When the app returns to the foreground, if an ad is loaded and not expired, it displays automatically.
- The banner is automatically hidden while the App Open Ad is visible and restored when it closes.
- App Open Ads are suppressed while an interstitial or rewarded video is being shown.
Creating a Custom Ad Provider
To add support for a different ad network, create a new class extending AdProviderHandler:
public class MyCustomHandler : AdProviderHandler
{
public MyCustomHandler()
{
providerType = AdProvider.AdMob; // or add a new enum value
}
protected override async Task<bool> InitProviderAsync()
{
// Initialize your SDK here
return true;
}
public override void ShowBanner() { /* ... */ }
public override void HideBanner() { /* ... */ }
public override void DestroyBanner() { /* ... */ }
public override void RequestInterstitial() { /* ... */ }
public override void ShowInterstitial(AdvertisementCallback callback) { /* ... */ }
public override bool IsInterstitialLoaded() { /* ... */ }
public override void RequestRewardedVideo() { /* ... */ }
public override void ShowRewardedVideo(AdvertisementCallback callback) { /* ... */ }
public override bool IsRewardedVideoLoaded() { /* ... */ }
}
Use the protected helpers for callbacks:
OnProviderAdLoaded(AdType)— call when an ad finishes loadingOnProviderAdDisplayed(AdType)— call when an ad appears on screenOnProviderAdClosed(AdType)— call when an ad is dismissedHandleAdLoadFailure(adType, errorMessage, ref retryAttempt, retryAction)— call on load failure for automatic exponential retryAdsManager.CallEventInMainThread(callback)— use to marshal SDK callbacks to the main thread
Troubleshooting
Common Issues
This is normal when the Google Mobile Ads Unity Plugin is not imported. The UMP consent flow requires the AdMob SDK. The system gracefully skips it and proceeds to initialization with whatever provider is configured.
Try these steps:
- Force a recompile: right-click any .cs file and select Reimport.
- Open
Window > Ragendom Core > Define Managerand verify the detection status. - If needed, manually enable the
MODULE_ADMOBtoggle.
This is expected behavior. After showing a rewarded video, the ad is consumed and a new one must be loaded. The system automatically calls RequestRewardBasedVideo() after showing, but loading takes time. You can check IsRewardBasedVideoLoaded() before showing, and disable your reward button when it returns false.
Check the following:
- Providers are set to AdMob (not Dummy) in MonetizationSettings.
- Your AdMob App ID is correctly entered in the Google Mobile Ads Settings.
- Your device's hashed ID is in the Test Devices list for test ads.
- Enable Verbose Logging in MonetizationSettings and check the device logcat for error messages.
- Ensure your device has an internet connection.
Interstitials have multiple guards. Check:
- Timing: The cooldown timer may not have elapsed. Use
ignoreConditions: truefor testing. - No-ads: If
DisableForcedAd()was called, interstitials are permanently blocked. - Custom conditions: If you assigned delegates to
AdsManager.InterstitialConditions, any returningfalseblocks the ad. - Module active: Ensure
isModuleActiveistruein MonetizationSettings.
All AdMob code is wrapped in #if MODULE_ADMOB preprocessor guards. If you see build errors mentioning GoogleMobileAds, it means the define is active but the SDK is not properly installed. Either:
- Re-import the Google Mobile Ads Unity Plugin, or
- Disable
MODULE_ADMOBinWindow > Ragendom Core > Define Manager.
The system uses these PlayerPrefs keys: "ADS_SAVE" (no-ads state) and "FIRST_LAUNCH" (first-launch interstitial delay). If you need to reset the ad state during testing, delete these keys via PlayerPrefs.DeleteKey("ADS_SAVE") or clear all PlayerPrefs.
Going to Production
Before publishing your app with real ads, complete this checklist:
Create Real Ad Units
Log in to Google AdMob. Create ad units for each format (Banner, Interstitial, Rewarded Video, and optionally App Open Ad) for each platform (Android, iOS).
Replace Test Ad Unit IDs
In your MonetizationSettings asset, replace all test ad unit IDs with your real production IDs. The inspector will stop showing the "test ID" warning once you do.
Configure UMP Consent
If your app targets users in the EEA (European Economic Area), ensure isUMPEnabled is true. Set up your GDPR consent message in the AdMob console under Privacy & messaging.
Configure IDFA (iOS Only)
If targeting iOS, enable isIDFAEnabled and customize the trackingDescription string. This shows the App Tracking Transparency dialog before initializing ads.
Remove Test Device IDs
Clear the Test Devices list in MonetizationSettings. Leaving test device IDs in production won't cause harm, but is unnecessary.
Disable Debug Settings
Set verboseLogging to false, debugMode to false, and umpDebugMode to false.
Tune Interstitial Timing
Adjust the interstitial timing values for your game's pacing. Aggressive interstitial frequency hurts user retention. Recommended starting values:
- First start delay: 60–120 seconds
- Session start delay: 30–60 seconds
- Between interstitials: 30–60 seconds
Build a Release Version
Build for your target platform with the development build option unchecked. Test thoroughly on a real device with a real internet connection.
Appendix
Enums Reference
AdProvider
| Value | Int | Description |
|---|---|---|
Disable | 0 | Ad format is completely turned off. |
Dummy | 1 | Built-in test provider. Works everywhere, no SDK needed. |
AdMob | 2 | Google AdMob. Requires SDK on device. |
AdType
| Value | Int |
|---|---|
Banner | 0 |
Interstitial | 1 |
RewardedVideo | 2 |
BannerPosition
| Value | Int |
|---|---|
Bottom | 0 |
Top | 1 |
ConsentRequirementStatus
| Value | Description |
|---|---|
Unknown | Status has not been determined yet. |
NotRequired | User is outside the EEA; no consent needed. |
Required | User is in the EEA; GDPR consent is required. |
AuthorizationTrackingStatus (iOS only)
| Value | Description |
|---|---|
NOT_DETERMINED | ATT dialog not yet shown. |
RESTRICTED | Parental/MDM restriction prevents the request. |
DENIED | User denied tracking. |
AUTHORIZED | User granted tracking. |
DebugGeography
| Value | Description |
|---|---|
Disabled | Use real geography. |
EEA | Simulate European Economic Area (triggers consent flow). |
NotEEA | Simulate non-EEA region. |
PlayerPrefs Keys
| Key | Type | Description |
|---|---|---|
"ADS_SAVE" | string (JSON) | Stores AdSave object. Contains isForcedAdEnabled (no-ads purchase state). |
"FIRST_LAUNCH" | int | Set to 1 after first launch. Used to determine which interstitial start delay to use. |
Assembly Definitions
The asset uses Assembly Definitions (.asmdef) for proper compilation isolation. If your project uses asmdef files and you need to reference the ad system, add Ragendom.Monetization to your assembly's references.
| Assembly | Type | References |
|---|---|---|
Ragendom.Core | Runtime | — |
Ragendom.Defines | Runtime | — |
Ragendom.Defines.Editor | Editor | Ragendom.Defines |
Ragendom.Monetization | Runtime | Ragendom.Core, Ragendom.Defines, Unity.TextMeshPro, UnityEngine.UI |
Ragendom.Monetization.Editor | Editor | Ragendom.Core, Ragendom.Defines, Ragendom.Monetization |
Ragendom.Monetization.Ads.Editor | Editor | Ragendom.Core, Ragendom.Defines, Ragendom.Monetization |
Ragendom.Examples | Runtime | Ragendom.Core, Ragendom.Defines, Ragendom.Monetization, Unity.TextMeshPro, UnityEngine.UI |
Ragendom.Examples.Editor | Editor | Ragendom.Core, Ragendom.Defines, Ragendom.Monetization, Ragendom.Examples, Unity.TextMeshPro, UnityEngine.UI |
Ragendom Ad Mediation — Built by Ragendom