Our complete CloudX Unity SDK integration guide is available on our docs site, https://docs.cloudx.io/en/unity/integration.
Click here to download the latest .unitypackage Github release.
This repository is also a runnable Unity demo project. It shows a working CloudX integration for banner, MREC (the 300x250 medium rectangle), interstitial and rewarded ads, plus a First Look flow that falls back to AdMob.
Requirements:
- Unity 6 LTS
6000.0.60f1(seeProjectSettings/ProjectVersion.txt) - iOS: Xcode
- Android: the Unity Android Build Support module
Open the project in Unity and press Play, or build to a device from File > Build Settings. Build to a device for anything beyond a smoke test: the CloudX ad callbacks are no-ops in the Editor, so ads neither load nor show there.
The app opens on a launch screen that picks a demo flow. Nothing SDK-related happens until you
choose, which is deliberate: the iOS tracking prompt and CloudXSdk.Initialize belong to the flow
you picked, not to app start.
OptionsScene ── General ──> GeneralScene (the full CloudX surface)
└─ First Look ──> FirstLookScene (CloudX first, AdMob fallback)
There is no back navigation; relaunch the app to pick the other flow.
| Scene | Script holding the SDK calls | What it demonstrates |
|---|---|---|
Assets/Scenes/OptionsScene.unity |
Assets/Scripts/OptionsScreen.cs |
Picking a flow. No SDK calls. |
Assets/Scenes/GeneralScene.unity |
Assets/Scripts/GeneralScreen.cs |
Every ad format, straight CloudX. |
Assets/Scenes/FirstLookScene.unity |
Assets/Scripts/FirstLook/ |
CloudX first, AdMob as the fallback. |
Assets/Scripts/AdScreenUi.cs is the layout shared by the two ad screens. It is demo-only: it wires
buttons and reflows on rotate, and contains no SDK calls. Ignore it when reading the integration.
OptionsScene is index 0 in the build settings, so it is what launches. Each button calls
SceneManager.LoadScene with a scene name, which only resolves for scenes listed in
File > Build Settings, so all three are listed there.
A third flow, Arbiter/TPA, is not implemented yet and its button stays hidden.
The straight CloudX integration, one button per format. GeneralScreen.cs is the file to read: it is
the SDK call sequence and nothing else.
The screenshot has both a banner (top) and an MREC (bottom) on screen, which is why two buttons read "Show Bottom Banner" and "Hide MREC" - the labels track what the next tap will do.
| Button | Behaviour |
|---|---|
| Show Interstitial | Shows the preloaded interstitial, then reloads on close. |
| Show Rewarded | Same for rewarded, and logs the reward the user earned. |
| Show/Show edge Banner | First tap shows the banner. Each later tap moves it to the opposite edge, so you can cycle it around the screen. |
| Show/Hide MREC | Toggles MREC visibility. |
The status line at the bottom reports initialization; the text beside each fullscreen button reports that format's load state.
The initialization sequence, in the order Start() runs it:
- Resolve iOS tracking first. The SDK never prompts, and treats an undetermined ATT status as opted out, so a load issued before ATT resolves goes out as do-not-track and never fills - even if the user later grants permission. On Android this step is a no-op.
- Set privacy and user data (
SetHasUserConsent,SetDoNotSell, user and app key/values). These belong beforeInitializeso they apply to the first auction. - Subscribe to the initialization callbacks, then call
CloudXSdk.Initialize. - Create and load ads only after
OnSdkInitialized. Buttons stay inert until then, so no tap can reach aLoadbefore the SDK is ready.
Both initialization callbacks originate in native code, so neither is guaranteed to arrive. The demo re-enables the UI after 15 seconds regardless, because a permanently untappable screen is a worse failure than letting a tester poke the not-ready paths.
First Look gives CloudX the first chance to fill a placement and falls back to AdMob only when CloudX cannot. The full pattern is documented at https://docs.cloudx.io/en/unity/integrations/first-look; this screen is a working copy of it, meant to be lifted into a publisher app.
The rules the controllers implement:
- CloudX is asked first. AdMob is loaded lazily, only after CloudX reports a load failure.
- The two are never loaded in parallel, so the fallback costs nothing when CloudX fills.
Show()prefers a ready CloudX ad over a ready AdMob one, and returnsfalsewhen neither is ready. For interstitial and rewarded the caller just carries on with the game; the demo says so and reloads. For banner and MREC aShow()with nothing ready is remembered, and the ad appears as soon as either source loads;Hide()cancels that.- If CloudX initialization fails outright, the controllers skip the CloudX leg and serve AdMob directly, rather than waiting for load callbacks that a failed init never delivers.
- A failed load or show is retried with a capped backoff (2 s, 4 s, 8 s ... up to 60 s), reset by the next successful load. A fixed short retry would turn sustained no-fill into a tight request loop against the fallback network.
The status text names which SDK won, so you can see the pattern working:
Left: CloudX filled. Right: the same button after CloudX no-filled, showing Google's test creative.
Everything the flow needs lives in Assets/Scripts/FirstLook, and none of it calls into the General
screen, so the folder can be copied out whole:
| File | Role |
|---|---|
FirstLookSource.cs |
The CloudX / AdMob enum every event reports. |
FirstLookAdController.cs |
Shared base: the CloudX/AdMob bookkeeping, load events, and dispose. |
FirstLookFullscreenController.cs |
Base for the fullscreen formats (interstitial, rewarded). |
FirstLookInlineController.cs |
Base for the inline formats (banner, MREC), including refresh-off. |
FirstLookInterstitialController.cs |
The interstitial SDK calls. |
FirstLookRewardedController.cs |
The rewarded SDK calls, plus the reward callback. |
FirstLookBannerController.cs |
The banner SDK calls. |
FirstLookMrecController.cs |
The MREC SDK calls. |
FirstLookConfig.cs |
AdMob ad unit ids, and the fallback test switch below. |
FirstLookScreen.cs |
Initializes both SDKs, wires the controllers to the buttons. |
Each format is a thin subclass over a shared base, so the fallback rule is written once. To integrate
one format, take four files: FirstLookSource.cs, FirstLookAdController.cs, the family base
(FirstLookFullscreenController.cs for interstitial or rewarded, FirstLookInlineController.cs for
banner or MREC) and that format's controller. The bases are small and format-agnostic.
To see the fallback path yourself, set ForceCloudXNoFill = true in FirstLookConfig.cs and rebuild.
It points CloudX at an unknown ad unit, so every CloudX load fails and AdMob serves instead.
First Look covers all four formats. Banner and MREC toggle Show/Hide, and the button label names the
SDK that filled (e.g. Hide Banner (CloudX)). The banner sits at the top in both orientations; the
MREC is a 300x250 at the bottom.
Both inline ads shown at once, filled by CloudX; the labels read Hide Banner (CloudX) and
Hide MREC (CloudX).
Banner and MREC keep auto-refresh off so a background reload never overrides the First Look
source decision. CloudX inline auto-refresh is opt-out - showing an inline ad starts it unless the ad
unit was first passed to Stop*AutoRefresh - so the controllers call StopBannerAutoRefresh /
StopMrecAutoRefresh before create and never call the Start* counterparts. (GeneralScreen
restarts refresh on focus; First Look deliberately does not.)
Disable automatic refresh on your AdMob banner and MREC ad units.
This is the one step the code cannot do for you. The Google Mobile Ads Unity plugin has no refresh API: a
BannerViewloads once, and whether it refreshes afterwards is decided solely by the ad unit's Automatic refresh setting in the AdMob console, in the settings of each banner and MREC ad unit. If that setting is on, AdMob swaps the creative on its own schedule, and every swap silently replaces the ad that won the First Look pass - CloudX never gets asked again for that slot. Set it to Disabled on every AdMob unit you use as a First Look fallback.The demo's Google test units are configured by Google, not by this project, so treat them only as a way to see the fallback render; the setting above is about the units you replace them with.
The First Look flow needs the Google Mobile Ads Unity plugin, which this project pulls in as a
package (Packages/manifest.json) along with the External Dependency Manager it requires. Unity
resolves both on open, so no manual import step is needed.
If you copy the First Look folder into your own project, add the same plugin there; the CloudX SDK itself does not depend on it.
The demo ships with CloudX demo dashboard IDs so it runs without an account. To point it at your own CloudX app:
- Replace the app key and ad unit IDs in
Assets/Scripts/DemoConfig.cs. - Set the bundle identifier registered for that app in Unity under
Project Settings > Player > Identification (
ProjectSettings/ProjectSettings.asset).
For iOS device builds also set your own Signing Team ID under Project Settings > Player > Signing. It ships empty on purpose.
Bid requests are authorized per app key and bundle identifier, so both have to match your dashboard app or the SDK gets no fill.
The AdMob ad units in FirstLookConfig.cs are Google's official test units and stay valid as they
are; replace them with your own AdMob units when you take this into production, and set
Automatic refresh to Disabled on the banner and MREC ones (see the First Look section for why).
The project is configured for the Simulator SDK. To build for a physical iOS device, switch Target SDK to Device under Project Settings > Player > Other Settings before building.





