A drop-in, production-ready manager for Unity LevelPlay (Ads Mediation). Add one component, fill in your keys, and get SDK initialization, GDPR/CCPA/COPPA consent, interstitial/rewarded/banner lifecycle with exponential-backoff retries, impression-level revenue events (ILRD), deep Unity Ads & ironSource demand diagnostics, an in-editor LevelPlay Manager window built with modern UI Toolkit, and a unified custom inspector — all without writing mediation boilerplate in your game code.
- Why this package
- Installation
- Quick Start
- LevelPlay Manager (UI Toolkit Editor Tool)
- Unity Ads & LevelPlay Step-by-Step Integration Guide
- Custom Inspector
- Configuration Reference
- API Reference
- Events
- Fallback Behavior (Rewarded Ads)
- Privacy & Consent (GDPR / CCPA / COPPA)
- App Tracking Transparency (iOS)
- Impression-Level Revenue (ILRD) → Analytics
- Extending: Game-Specific Subclass
- Runtime Debug Overlay (F8)
- Production Release Checklist
- Architecture
- Troubleshooting / FAQ
- License
Integrating LevelPlay directly usually requires writing ~500 lines of lifecycle, error retry, threading, and consent plumbing into every project. Developers frequently encounter tricky edge cases:
- What happens when a rewarded ad isn't ready when the player taps the button?
- Why is Unity Ads missing or failing to fill even though the adapter is installed?
- Did you turn off the Test Suite before shipping to Google Play or the App Store?
- Did you configure GDPR and CCPA before initializing the SDK?
LevelPlayHelper centralizes all of this once, tested, and versioned — so your game only handles game-specific ad cadence and UI rewards.
- Open Window > Package Manager
- Click + > Add package from git URL...
- Paste:
https://github.com/wagenheimer/UnityLevelPlayHelper.git
To pin a specific release:
https://github.com/wagenheimer/UnityLevelPlayHelper.git#vX.Y.Z
| Requirement | Version |
|---|---|
| Unity | 2022.3 LTS or newer (tested up to Unity 6) |
Ads Mediation package (com.unity.services.levelplay) |
9.5.1 (stable UPM release) |
| Native dependency resolver | Mobile Dependency Resolver (MDR) or EDM4U |
- Add the
LevelPlayHelpercomponent to a persistent GameObject in your first scene (or use a prefab underResources). - Open Tools > Wagenheimer > Level Play Helper > LevelPlay Manager... (or select the component Inspector).
- Fill in your App Key and Ad Unit IDs for Android and/or iOS (or connect via the Cloud API tab to sync automatically).
- Press Play — mock ads load automatically in the Unity Editor for instant testing!
// 1. Show an interstitial ad
LevelPlayHelper.Instance.ShowInterstitial();
// 2. Show a rewarded ad (reward callback only fires when earned)
LevelPlayHelper.Instance.ShowRewardedAd(() =>
{
player.AddCoins(50);
});
// 3. Show a banner ad
LevelPlayHelper.Instance.ShowBanner();The package features a modern UI Toolkit dashboard (LevelPlaySetupWindow) shared with the component Inspector (LevelPlayHelperEditor). It organizes mediation management into 4 functional hubs:
┌────────────────────────────────────────────────────────────────────────┐
│ LevelPlay Manager [v2.11.0] [Dashboard] [Ad Units] [Docs] [Sync] │
│ SDK: com.unity.services.levelplay (v9.5.1) │
├────────────────────────────────────────────────────────────────────────┤
│ [ Credentials & Formats ] [ Rules & Privacy ] [ Testing ] [ Cloud ] │
└────────────────────────────────────────────────────────────────────────┘
- Live Platform Switch: Toggle between Android and iOS configurations.
- Two-Way Data Binding: Built on Unity's native
SerializedObjectsystem with full Undo/Redo (Ctrl+Z) support. - Real-Time Validation Badges:
OK(Valid ID formatted correctly)WARN(Empty format — automatically disabled)FAIL(Placeholder detected or malformed character sequence)
- Ad Pacing Rules (
AdsConfiguration): Configures minimum intervals, initial interval pacing, and reduction rates. - Privacy & Consent Regulations (
ConsentConfiguration):- GDPR: Configures user consent state before initialization.
- CCPA / CPRA: User opt-out flags for data sales.
- COPPA: Child-directed treatment flags for minors.
- LevelPlay Test Suite: Toggle and validate on-device test suite tools.
- In-Game Debug Overlay: Enable the runtime UI Toolkit overlay (
ADS DBG/F8). - Editor Mock Test Mode: Safe simulation of ad load and display callbacks in the Unity Editor without live SDK overhead.
- Development Build: Quick toggle for Unity development build flags.
Hosts two powerful verification panels:
- Automated Setup Checklist: 8 collapsible categories scanning packages, resolvers, permissions (
AD_ID,INTERNET), manifests, and code usage. - Cloud API & Demand Networks Hub: Connects directly to the LevelPlay Management API to inspect applications, ad units, and demand network instances.
LevelPlay requires concurrent demand from both ironSource and Unity Ads to maximize auction competition and fill rates.
Because Unity migrated to the new Unity Cloud Dashboard, follow these 4 steps in the Cloud API tab:
flowchart LR
A["1. Client Adapter<br/>(ISUnityAdsAdapter)"] --> B["2. SDK Networks<br/>(Link Org & Key)"]
B --> C["3. App Instances<br/>(Game ID & Formats)"]
C --> D["4. Live Verification<br/>(Fetch & Verify)"]
- Open Ads Mediation > Network Manager in Unity.
- Verify
Unity Adsadapter is installed (version5.14.0+). - The helper will detect
ISUnityAdsAdapterDependencies.xmlautomatically.
- In the helper, click Open SDK Networks (navigates to
https://platform.ironsrc.com/partners/next/networks). - Locate Unity Ads and enter:
- API Key: Your Unity Ads API Key.
- Organization Core ID: Your Unity Organization ID (e.g.
22730).
⚠️ IMPORTANT: Turn OFF the toggle for Bidder auto-setup. (The new Unity Cloud dashboard uses manual instance mapping; keeping auto-setup on will produce an error).- Click Save.
- In the helper, click Open Instances (navigates to
https://platform.ironsrc.com/partners/next/mediation/instances/). - Select your app (iOS or Android).
- Enter your Game ID from the Unity Cloud Dashboard (Monetization > Apps).
- Click + Add instance for each ad format:
- Rewarded: Name =
UnityAds_Rewarded| Placement ID =Rewarded_iOS(orRewarded_Android) | Status = Active. - Interstitial: Name =
UnityAds_Interstitial| Placement ID =Interstitial_iOS(orInterstitial_Android) | Status = Active. - Banner: Name =
UnityAds_Banner| Placement ID =Banner_iOS(orBanner_Android) | Status = Active.
- Rewarded: Name =
- Click Save.
- Return to the Cloud API tab in Unity.
- Click Fetch & Verify Setup.
- The real-time table will audit all instances:
ironSource: LIVEUnity Ads: LIVE (UnityAds_Rewarded)[✓ Synced to Prefab]
Selecting any LevelPlayHelper (or your custom subclass) in the Unity hierarchy or project assets displays the full UI Toolkit editor:
- Quick Header: Displays current package version, SDK status, and direct buttons for Manager Window, Dashboard, and Documentation.
- Embedded Tabs: Switch between Credentials, Rules, Testing, and Diagnostics directly inside the Unity Inspector.
- Inspector Mode Adaptations: Clean layout designed specifically for standard Inspector widths with full data-binding support.
| Field | Type | Default | Description |
|---|---|---|---|
androidAppKey / iosAppKey |
string | "" |
App Key from LevelPlay dashboard per platform. |
androidInterstitialAdUnitId / iosInterstitialAdUnitId |
string | "" |
Interstitial Ad Unit ID (empty = disabled). |
androidRewardedAdUnitId / iosRewardedAdUnitId |
string | "" |
Rewarded Ad Unit ID (empty = disabled). |
androidBannerAdUnitId / iosBannerAdUnitId |
string | "" |
Banner Ad Unit ID (empty = disabled). |
bannerPosition |
BannerPositionPreset |
BottomCenter |
One of 9 standard LevelPlay banner positions. |
adsConfig |
AdsConfiguration |
— | Cadence intervals and reduction thresholds. |
consentConfig |
ConsentConfiguration |
- | GDPR, CCPA/CPRA, and COPPA compliance flags. |
trackingConfig |
TrackingConfiguration |
- | ATT request toggle and the NSUserTrackingUsageDescription purpose string (iOS). |
enableTestSuite |
bool | false |
Launches on-device LevelPlay Test Suite after init. |
enableDebugOverlay |
bool | true |
Enables the runtime ADS DBG / F8 diagnostic overlay. |
LevelPlayHelper.Instance: Static singleton access.LevelPlayHelper.Instance.Initialize(): Applies privacy settings and initializes the SDK.LevelPlayHelper.Instance.IsSdkInitialized: True once initialization finishes.LevelPlayHelper.Instance.TrackingState: CurrentTrackingAuthorizationState(NotSupportedoutside iOS).LevelPlayHelper.Instance.SetUserConsent(bool): Updates and persists GDPR consent inPlayerPrefs.
ShowInterstitial(): Displays interstitial ad if ready; initiates reload on failure.IsInterstitialReady(): Returns readiness state for interstitials.ShowRewardedAd(Action onReward): Shows rewarded ad; invokesonRewardcallback only when earned.IsRewardedAdReady(): Returns readiness state for rewarded ads.TryShowAd(Action onReward): Fallback method prioritizing rewarded ads over interstitials.ShowBanner()/HideBanner()/DestroyBanner(): Controls banner display and memory lifecycle.
All events are static, allowing subscription from any system without holding instance references:
LevelPlayHelper.OnSdkInitialized += config => { /* SDK ready */ };
LevelPlayHelper.OnInterstitialClosed += () => { /* Resume gameplay */ };
LevelPlayHelper.OnRewardedAdGranted += () => { /* Reward granted */ };
LevelPlayHelper.OnAdDisplayed += format => { /* Pause game audio */ };
LevelPlayHelper.OnAdClosed += format => { /* Resume game audio */ };
LevelPlayHelper.OnAdRevenuePaid += (adUnitId, revenue) => { /* ILRD analytics */ };
LevelPlayHelper.OnImpressionDataReady += data => { /* Raw SDK payload (background thread) */ };
LevelPlayHelper.OnTrackingAuthorizationCompleted += state => { /* ATT resolved (iOS) */ };OnAdClosed fires for both "Interstitial" and "Rewarded" (including a skipped rewarded),
so it is the right hook to restore anything paused when the ad opened:
LevelPlayHelper.OnAdDisplayed += format =>
{
if (format != "Banner") AdAudioPause.Pause(); // e.g. AudioListener.pause = true
};
LevelPlayHelper.OnAdClosed += format =>
{
if (format != "Banner") AdAudioPause.Resume();
};LevelPlayHelper resolves ATT before LevelPlay.Init() - the SDK reads the advertising identifier during initialization, so a request later in the session is too late for personalized fill.
TrackingConfig.requestAuthorization(defaulttrue) requests the native alert on iOS 14.5+.TrackingConfig.usageDescriptionis written toNSUserTrackingUsageDescriptionby the package's[PostProcessBuild]step. Keep it specific - Apple rejects missing or vague purpose strings.- The native alert is shown once per install. The helper only requests it while the status is
NotDetermined. TrackingStateexposes the result andOnTrackingAuthorizationCompletedfires when it is known.
When another package owns the ATT request (for example com.wagenheimer.tracking), set
TrackingConfig.requestAuthorization to false and give the helper a gate before it is created:
LevelPlayHelper.InitializationGate = () => !TrackingConsent.IsRequired || TrackingConsent.IsResolved;Initialize() (including the automatic call from Start) waits for the gate (60s by default,
InitializationGateTimeoutSeconds) before calling LevelPlay.Init(). If the prefab is created
before the answer, the SDK still does not read the IDFA too early.
If you show a screen before the native alert, assign a coroutine before the helper initializes. The helper calls the ATT API when the coroutine completes. The pre-prompt must not call ATT itself and must offer a single "Continue"/"Next" action (App Store guideline 5.1.1(iv)).
LevelPlayHelper.PreTrackingPrompt = ShowTrackingPrePrompt;
private IEnumerator ShowTrackingPrePrompt()
{
myDialog.SetActive(true);
yield return new WaitUntil(() => !myDialog.activeSelf);
}ConsentGate is the reusable consent owner for projects that must ask before ads
initialize. Add it next to LevelPlayHelper on the same prefab and assign a
ConsentLocalization asset (create one from Assets > Create > Tools > Wagenheimer >
Level Play > Consent Localization).
LevelPlayHelper.prefab
LevelPlayHelper (ads)
ConsentGate (consent + standard dialog)
What it does:
- stores the answer in
PlayerPrefsunderUserConsent(the key the helper already reads); - calls
LevelPlayHelper.Instance.SetUserConsent(...)immediately; - while the answer is missing, keeps
LevelPlayHelper.InitializationGateclosed, soLevelPlay.Init()waits (60s by default) instead of running without consent; - shows the package's standard dialog on first launch, or you can call
Grant()/Deny()from your own UI.
The standard dialog is built at runtime with UI Toolkit - no prefab to import and no
localization package dependency. It reads every string from the localization asset and
falls back to English when a language is incomplete. Assign a theme or a legacy Font
on the gate when the default font does not cover your script (for example Korean).
ConsentLocalization has one entry per language and a requiredLanguageCodes list. The
Setup Checklist (and the LevelPlay Manager) find the gate in your prefabs/scenes and
report every required language that is missing or has an empty title, body, accept or
decline string.
To protect user experience and retain players even during ad network outages, ShowRewardedAd executes a graceful fallback strategy:
- Rewarded ad is ready → Displays ad and grants reward upon completion.
- Rewarded not ready, Interstitial is ready → Shows interstitial and grants reward immediately.
- No ads available → Grants reward directly without showing an ad.
In all cases, an ad reload is queued immediately with exponential backoff.
In the Unity Editor and Development Builds, tap the ADS DBG button or press F8 to open the runtime diagnostic HUD:
- WHY NOT LOADING Banner: Diagnoses the exact root cause of delivery failures (missing keys, consent not granted, paused units, mock state).
- State Machine Inspection: Real-time status (
Idle,Loading,Ready,Showing,Failed). - Live Event Log: Color-coded, thread-safe event log with instant Copy Report to clipboard.
- Interactive Triggers: Manually trigger ad loads, shows, banner toggles, and consent testing.
- Consent Gate Card: resolved/consent/stored state,
InitializationGatestatus, localization asset and resolved language, missing translations, Grant / Deny / Reset / Show dialog, one-click preview of every language and a copyable consent report.
Before building for release:
- Open LevelPlay Manager > Diagnostics and ensure all automated checklist items pass.
- Verify both ironSource and Unity Ads are marked
LIVEin the Cloud tab. - Ensure Enable Test Suite is disabled.
- Confirm real App Keys and Ad Unit IDs are entered (no placeholders).
- Verify native dependencies resolved (
Assets > External Dependency Manager > Android/iOS Resolver). - On Android, verify
AD_IDpermission is declared for target API 33+.
Your Game Logic
└── LevelPlayHelper (Singleton MonoBehaviour)
├── LevelPlayPrivacySettings (GDPR / CCPA / COPPA)
├── LevelPlayAdFormat (Rewarded / Interstitial / Banner)
└── Unity.Services.LevelPlay (Ads Mediation SDK v9.5.1)
├── ironSource Network Demand
└── Unity Ads Network Demand (Bidding & Waterfall)
Distributed under the MIT License.
Package Hub · Unity Utils · Build Pipeline · Cloud Save · Rate Control · IAP Helper · LevelPlay Helper · Native Social · Rewired Helper · Timeline Typewriter · Tk2d Porter · Tracking · I2 Localization
Explore every project at wagenheimer.com/opensource.