View as Markdown

Unity

The Ezoic Unity SDK lets you show Ezoic banner, rewarded, and interstitial ads in Unity games while relying on the native Android and iOS SDKs for ad loading, Prebid, Google Ad Manager, consent handling, pageview tracking, and remote configuration.

The Unity package is a C# bridge over the native SDKs. It does not reimplement the ad stack in C#, so your game code stays platform-agnostic and the same calls run as safe no-ops in the editor.

Requirements

  • Unity 2021.3 LTS or higher
  • Android SDK 24 or higher for Android apps, with Target API Level 34 or higher
  • iOS 15.0 or higher for iOS apps, built with Xcode 26.2 or higher
  • External Dependency Manager recommended to resolve the native libraries: Unity's External Dependency Manager 2.1 or higher, or Google's EDM4U 1.2.189 or higher, to install the iOS SDK with Swift Package Manager
  • Google Mobile Ads application ID provided by Ezoic

Installation

In Unity, open Window → Package Manager → + → Add package from git URL… and enter the package git URL pinned to a released version:

https://github.com/ezoic/ezoic-unity-sdk.git#v1.21.0

Or add it to your project's Packages/manifest.json dependencies:

{
  "dependencies": {
    "com.ezoic.ads": "https://github.com/ezoic/ezoic-unity-sdk.git#v1.21.0"
  }
}

The current Unity SDK version is 1.21.0, which uses native SDK 1.21.0 on iOS and Android (Google Mobile Ads 13 on iOS, 25.5.0 on Android).

Upgrading to 1.21.0: no code changes are needed. Banners now refresh automatically every 30 seconds, or at the interval Ezoic sets for the ad unit. On Android, Google Mobile Ads moves to 25.5.0 and InMobi now bids in Ezoic's Google Ad Manager auctions through Google's InMobi adapter, which the native SDK includes; if a custom mainTemplate.gradle or another plugin pins play-services-ads, allow 25.5.0. Swift Package Manager builds get native iOS SDK 1.21.0; CocoaPods builds do not (see iOS).

Upgrading to 1.20.0: no code changes are needed. With a current External Dependency Manager, the iOS SDK now installs as a Swift package instead of a CocoaPod; see iOS. Older EDM4U versions keep installing the CocoaPod, which gets no native iOS SDK updates after December 1, 2026.

Upgrading from 1.11.0 to 1.19.1:

  • iOS now requires 15.0 and Xcode 26.2, and Android requires Target API Level 34.
  • The native SDKs show a built-in consent dialog to users in GDPR regions, and ad loads for those users fail until they decide. Call EzoicAds.PresentConsentIfRequired after EzoicAds.Initialize and add a "Privacy settings" button, or turn the dialog off if you run your own consent platform. See Privacy and Consent.
  • iOS builds through CocoaPods (the EDM4U path) failed to compile in 1.11.0 and now build.
  • Calling EzoicAds.Initialize again, for example from a scene that loads twice, now reports success.
  • Android release builds made with Android Gradle Plugin 9 no longer crash at startup, and on iOS consent set with SetGDPRConsent or SetGPPConsent now reaches Google Mobile Ads, IMA and Amazon.

Platform Setup

Unity games still need the native platform setup required by Android and iOS. The package ships an Editor/EzoicDependencies.xml manifest so the External Dependency Manager for Unity (EDM4U) can resolve the native libraries automatically. Install EDM4U from the Unity Jar Resolver project.

Android

With EDM4U installed, the Android Resolver adds the native com.ezoic.sdk:ezoic-ads-sdk:1.21.0 library (from Maven Central) to your generated Gradle build — no manual dependency needed.

The native SDK serves through Google Ad Manager, which requires your application ID in the Android manifest. Enable Custom Main Manifest under Project Settings → Player → Android → Publishing Settings and add the meta-data entry inside the <application> tag of Assets/Plugins/Android/AndroidManifest.xml:

<manifest>
  <application>
    <meta-data
        android:name="com.google.android.gms.ads.APPLICATION_ID"
        android:value="ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY" />
  </application>
</manifest>

Replace the value with the Google Mobile Ads application ID provided for your account. A missing or incorrect app ID causes the app to crash on start. The application ID is usually provided by Ezoic and can be found in your Ezoic dashboard.

iOS

Install the native iOS SDK with Swift Package Manager through the External Dependency Manager: use Unity's External Dependency Manager 2.1 or higher (Unity 2022.3 or higher), or Google's EDM4U 1.2.189 or higher. Make sure Swift Package Manager Integration is on in the iOS Resolver settings (Edit → Project Settings → External Dependency Manager → iOS Resolver for Unity's version, Assets → External Dependency Manager → iOS Resolver → Settings for EDM4U, where it is on by default). The iOS Resolver then adds the https://github.com/ezoic/ezoic-swift-sdk-dist.git package (up to the next major version from 1.21.0) to the generated Xcode project and links its EzoicAdsSDK product to UnityFramework, instead of adding the CocoaPod. Xcode resolves the package, with Google Mobile Ads, Prebid Mobile and Amazon Publisher Services, when you open or build the project.

Without the External Dependency Manager, build the Xcode project from Unity, open Unity-iPhone.xcodeproj, choose File → Add Package Dependencies, enter https://github.com/ezoic/ezoic-swift-sdk-dist.git with Up to Next Major Version from 1.21.0, and add the EzoicAdsSDK product to the UnityFramework target. A Replace build regenerates the Xcode project without the package, so use Append or add it again.

CocoaPods (no further native updates). When Swift Package Manager Integration is off, or with an older EDM4U, the iOS Resolver adds pod 'EzoicAdsSDK', '~> 1.19' to the generated Podfile instead; run pod install in the build output directory if EDM4U has not already done so. The CocoaPods trunk becomes read-only on December 2, 2026: CocoaPods builds get native SDK 1.19.1 until 1.20.0 is published there, and no native iOS SDK updates after the last version published before December 1, 2026. Avoid installing Google Mobile Ads through both channels: if this package installs as a Swift package while another plugin installs the Google-Mobile-Ads-SDK CocoaPod, the app links two copies of Google Mobile Ads.

iOS requires a deployment target of 15.0 or higher, set under Project Settings → Player → iOS → Other Settings → Target minimum iOS Version.

Follow the Required App Setup for Ads to Serve in the iOS guide. These steps live in your app's Info.plist and directly affect fill, so complete all of them:

  • Adding the Google Mobile Ads application ID (GADApplicationIdentifier) and GADIsAdManagerApp to Info.plist
  • Adding NSUserTrackingUsageDescription to Info.plist (the SDK presents the App Tracking Transparency prompt for you before loading ads — biggest impact on fill)
  • Adding the SKAdNetworkItems identifiers from Ezoic's combined list, skadnetworkids.xml, to Info.plist (Apple does not read these from frameworks/SDKs, and Google's list alone misses Ezoic's other buyers)

Unity writes a new Info.plist whenever it replaces the Xcode project, so apply these entries to the generated project after each build. For the SKAdNetwork identifiers, run the command from SKAdNetwork identifiers in the Xcode build output directory, or add them from an editor script marked [PostProcessBuild].

app-ads.txt

For both platforms, host an app-ads.txt file at the root of the developer website listed on your app's store page (for example, https://example.com/app-ads.txt). It authorizes the buyers that may sell your inventory; a missing or incomplete file causes most programmatic demand to be filtered out. Ezoic provides the required entries — confirm the file is published and current.

Initialize the SDK

Initialize Ezoic once, early in your game's lifecycle, with your Ezoic-registered domain. Make the call from the Unity main thread (for example from a MonoBehaviour's Start). The optional callback reports (success, error).

using Ezoic.Ads;
using UnityEngine;

public class AdsBootstrap : MonoBehaviour
{
    void Start()
    {
        EzoicAds.Initialize("example.com", (success, error) =>
        {
            if (success)
            {
                Debug.Log("Ezoic Ads initialized. SDK version: " + EzoicAds.Version);
            }
            else
            {
                Debug.LogWarning("Ezoic Ads init failed: " + error);
            }
        });
    }
}

domain must match the domain configured for your site in Ezoic. The native Android and iOS SDKs both authenticate using the configured domain plus the app's bundle/package identifier — there is no client-side API key. EzoicAds.IsInitialized becomes true once initialization succeeds.

Add a Banner Ad

Construct an EzoicBannerAd with your ad unit id and a screen position, subscribe to its events, then call Load(). Show it once it loads.

using Ezoic.Ads;

// Adaptive banner anchored to the bottom of the screen.
var banner = new EzoicBannerAd(adUnitId: 12345, position: BannerPosition.Bottom);

banner.OnLoaded      += () => banner.Show();
banner.OnLoadFailed  += error => Debug.LogWarning("Banner failed: " + error);
banner.OnClicked     += () => Debug.Log("Banner clicked");
banner.OnImpression  += () => Debug.Log("Banner impression");
banner.OnSizeChanged += (width, height) =>
    Debug.Log($"Banner size: {width}x{height}");

banner.Load();

// later: banner.Hide(); banner.Show();
// when done: banner.Destroy();

Replace 12345 with your Ezoic ad unit id. Use Show() / Hide() to toggle visibility without reloading, and always call Destroy() when you are done with a banner to release the native ad.

When no ad fills, the banner collapses so it does not leave a blank gap. This is controlled by CollapseOnNoFill (default true). If a refresh does not fill, the previous ad stays visible. OnSizeChanged reports the displayed size, or 0×0 when collapsed.

Banners refresh automatically every 30 seconds, or at the interval Ezoic sets for the ad unit, while at least half of the banner is on screen and your app is in the foreground. You do not set a refresh timer in your app.

The banner constructor takes an optional size string. Pass null (the default) to request an adaptive banner sized by the native SDK, or a fixed size string such as "320x50":

// Fixed 320x50 banner at the top of the screen.
var banner = new EzoicBannerAd(adUnitId: 12345, position: BannerPosition.Top, size: "320x50");

Common fixed size strings include:

  • "320x50": standard banner
  • "320x100": large banner
  • "300x250": medium rectangle
  • "468x60": full banner
  • "728x90": leaderboard

BannerPosition supports Top, Bottom, TopLeft, TopRight, BottomLeft, BottomRight, and Center.

EzoicBannerAd raises these events, all delivered on the Unity main thread:

  • OnLoaded
  • OnLoadFailed(string error)
  • OnClicked
  • OnImpression
  • OnSizeChanged(int width, int height)

Add a Rewarded Ad

Rewarded ads are full-screen ads that grant an in-app reward when the user finishes watching. Load one imperatively ahead of time (for example, at the start of a level), subscribe to its events, then present it at a natural break. The static Load hands you a ready instance through its onLoaded callback.

using Ezoic.Ads;

EzoicRewardedAd.Load(
    adUnitId: 34567,
    onLoaded: ad =>
    {
        ad.OnUserEarnedReward += (type, amount) =>
            Debug.Log($"Reward earned: {amount} {type}");
        ad.OnShown        += () => Debug.Log("Rewarded shown");
        ad.OnDismissed    += () => Debug.Log("Rewarded dismissed");
        ad.OnFailedToShow += error => Debug.LogWarning("Show failed: " + error);
        ad.OnImpression   += () => Debug.Log("Rewarded impression");
        ad.OnClicked      += () => Debug.Log("Rewarded clicked");

        if (ad.IsLoaded)
        {
            ad.Show();
        }
        // when finished with it: ad.Destroy();
    },
    onFailed: error => Debug.LogWarning("Rewarded load failed: " + error));

Replace 34567 with your Ezoic ad unit id. The reward type and amount come from the reward configured on the Google Ad Manager rewarded ad unit. Load and Show() are separate steps; guard Show() behind IsLoaded. Load a new EzoicRewardedAd for each reward opportunity, and call Destroy() when you are done with an instance.

Add an Interstitial Ad

Interstitial ads are full-screen ads shown at natural transition points (for example, between levels or screens). They grant no reward. Like rewarded ads, load one ahead of time and present it at a break.

using Ezoic.Ads;

EzoicInterstitialAd.Load(
    adUnitId: 23456,
    onLoaded: ad =>
    {
        ad.OnShown        += () => Debug.Log("Interstitial shown");
        ad.OnDismissed    += () => Debug.Log("Interstitial dismissed");
        ad.OnFailedToShow += error => Debug.LogWarning("Show failed: " + error);
        ad.OnImpression   += () => Debug.Log("Interstitial impression");
        ad.OnClicked      += () => Debug.Log("Interstitial clicked");

        if (ad.IsLoaded)
        {
            ad.Show();
        }
        // when finished with it: ad.Destroy();
    },
    onFailed: error => Debug.LogWarning("Interstitial load failed: " + error));

Replace 23456 with your Ezoic ad unit id. Load and Show() are separate steps; guard Show() behind IsLoaded. Load a new EzoicInterstitialAd for each opportunity, and call Destroy() when you are done with an instance.

Try the Sample

The package ships a Basic Integration sample: a single MonoBehaviour with an on-screen control panel that initializes the SDK and loads, shows, hides, and destroys every ad type while logging each ad event.

To import it, open Window → Package Manager, select Ezoic Ads in the package list, open the Samples tab, and click Import next to Basic Integration. Then attach the imported EzoicAdsDemo script to a GameObject in an empty scene, set your domain and ad unit ids in the Inspector, and build to a device.

Example Project

For a complete, ready-to-open project, see the Ezoic Unity SDK example on GitHub. It is a minimal Unity project that installs this SDK through the UPM git URL and shows how to test your ad code without a device:

  • Assets/App/AdsBootstrap.cs: an app-style integration that initializes the SDK, then loads a banner, an interstitial, and a rewarded ad, recording every outcome.
  • Assets/Tests/EditMode/: tests for the synchronous API surface (nothing throws, IsInitialized and Version defaults are correct).
  • Assets/Tests/PlayMode/: tests that initialization and load callbacks are always delivered on the Unity main thread, never inline.
  • .github/workflows/ci.yml: runs both test suites headlessly on every push with GameCI.

Open the folder in Unity Hub (Unity 6000.3 LTS; any 2021.3 or newer editor works if you adjust ProjectSettings/ProjectVersion.txt). Unity resolves the SDK from GitHub automatically. Run the tests from Window → General → Test Runner.

The native SDKs include an IAB TCF consent dialog that is on by default. It only appears for users in GDPR regions; everywhere else nothing is shown and ads load as usual. In GDPR regions, ad loads wait for the user's decision and fail without one, so:

  1. Ask for consent once per launch, right after Initialize. You don't need to wait for the init callback.
  2. Add an always-reachable "Privacy settings" button that calls PresentConsentSettings. TCF policy requires that users can change or withdraw consent at any time.
EzoicAds.Initialize("example.com", (success, error) => { /* ... */ });

EzoicAds.PresentConsentIfRequired(result =>
{
    // result.Outcome: NotRequired, AlreadyDecided, Decided (see result.Decision),
    // Dismissed (ask again later), AlreadyPresenting, or Failed (see result.Error).
    Debug.Log("Consent: " + result);
});

// "Privacy settings" button handler:
EzoicAds.PresentConsentSettings(result => Debug.Log("Consent settings: " + result));

// Show the button only where it applies (null until initialization completes):
bool showPrivacyButton = EzoicAds.IsConsentRequired == true;

If your app already runs another consent platform (Google UMP, OneTrust, and so on), turn the built-in dialog off. The SDK then reads that platform's IABTCF_* values:

EzoicAds.Initialize(new EzoicConfiguration("example.com") { CmpEnabled = false }, (success, error) => { /* ... */ });

You can also pass consent signals yourself. SetGDPRConsent makes the built-in dialog stand down for the current launch only, so call it before Initialize on every launch:

EzoicAds.SetGDPRConsent(true, "TCF_CONSENT_STRING");
EzoicAds.SetGPPConsent("GPP_STRING", "7");
EzoicAds.SetSubjectToCOPPA(false);

EzoicAds.ResetConsent() clears the stored decision so the dialog shows again, which is useful for testing.

For platform-specific consent behavior, see the Android privacy section and iOS privacy section.

Pageview Tracking

The native SDKs handle their platform-specific automatic pageview tracking. If your game changes screens, you can also track a pageview manually:

EzoicAds.TrackPageview();

Troubleshooting

Native library unresolved

If the build fails to find the native Ezoic library, confirm the External Dependency Manager for Unity (EDM4U) is installed. It reads the package's dependency manifest and resolves the native Android library and the iOS Swift package (or CocoaPod) for you; without it you must add the Gradle dependency and the Swift package (or Podfile line) manually.

No ads in the editor

Ads only serve on Android and iOS devices. In the Unity editor (and any other platform) the SDK runs as a safe no-op stub: calls never throw, load callbacks report failure, EzoicAds.IsInitialized is false, and EzoicAds.Version is an empty string. Build to a device to see ads.

iOS pods not installed

This applies only when the iOS SDK installs as a CocoaPod (see iOS). After Unity generates the Xcode project, EDM4U writes the EzoicAdsSDK pod into the Podfile. If pods are missing, run pod install in the Xcode build output directory. Also confirm the Google Mobile Ads application ID and the App Tracking Transparency description are present in Info.plist.