Skip to content

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cloudx-unity

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.

Demo app

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 gives CloudX the first chance and falls back to AdMob.

Requirements:

  • Unity 6 LTS 6000.0.60f1 (see ProjectSettings/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.

App flow

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.

Options screen

Options screen with General and First Look buttons

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.

General screen

The straight CloudX integration, one button per format. GeneralScreen.cs is the file to read: it is the SDK call sequence and nothing else.

General screen showing a top banner and an MREC at once

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:

  1. 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.
  2. Set privacy and user data (SetHasUserConsent, SetDoNotSell, user and app key/values). These belong before Initialize so they apply to the first auction.
  3. Subscribe to the initialization callbacks, then call CloudXSdk.Initialize.
  4. Create and load ads only after OnSdkInitialized. Buttons stay inert until then, so no tap can reach a Load before 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 screen

First Look screen with the interstitial and banner buttons

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.

It covers two formats: interstitial and banner. Those are the two shapes the rule has to handle - a fullscreen ad that is consumed by being shown, and an inline ad that stays on screen and therefore needs an explicit pass cycle. Rewarded follows the interstitial exactly and MREC follows the banner exactly, so the screen would only repeat itself; the General screen already shows the SDK calls for all four formats. This screen is about the controller, not about format coverage.

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 returns false when neither is ready. For the interstitial the caller just carries on with the game; the demo says so and reloads. For the banner a Show() 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:

CloudX interstitial served on the First Look screen Google AdMob test interstitial served after CloudX no-fill

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:

File Role
FirstLookInterstitialController.cs The whole interstitial flow, self-contained.
FirstLookBannerController.cs The whole banner flow, self-contained, including the pass cycle.
FirstLookSource.cs The CloudX / AdMob enum every event reports.
FirstLookConfig.cs AdMob ad unit ids, the banner pass cooldown, and the fallback test switch below.
FirstLookScreen.cs Initializes both SDKs, wires the controllers to the buttons.

To integrate one format, copy two files: that format's controller and FirstLookSource.cs. Each controller is one file you can read top to bottom - state, the entry points, then each SDK's callbacks - with no base class to chase. The two controllers repeat about fifty lines of ad-unit and dispose bookkeeping between them; that is deliberate, so neither file drags a shared base along into your project.

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.

The banner toggles Show/Hide and the button label names the SDK that filled (e.g. Hide Banner (CloudX)). It sits at the top in both orientations.

First Look screen with the CloudX banner at the top

The banner pass cycle

A banner is not consumed the way a fullscreen ad is, so it needs one thing the interstitial does not. One pass is one ad opportunity: CloudX is asked first, AdMob only if CloudX fails, and the winner goes on screen. Putting an ad on screen spends the pass - CloudX inline ads report only load and click, and a load into a view that is already visible renders straight away, so that is the one moment the code can treat as "this fill has been used". The screen then schedules the next pass FirstLookConfig.PassCooldownSeconds later (30 s by default), and that pass starts at CloudX again.

Without the cycle the first fill would latch: after one CloudX no-fill the AdMob fallback would own the placement until the scene was destroyed, and CloudX would never get another first look.

Three details worth copying as they are:

  • Reloading is in place, not a recreate - LoadBanner on the existing view, allowed because refresh was stopped for that ad unit - so a visible ad is replaced only once the new one has filled, and the slot never blanks.
  • The cycle only turns while an ad is on screen. Hiding cancels the pending pass, so a hidden slot never keeps requesting in the background, and showing it again puts the same ad back up and restarts the cooldown from that tap. The screen still preloads once before the first tap, so an ad is ready when the user asks for it.
  • An ad the AdMob console refreshed on its own does not count as a pass. Only a fill the controller asked for spends one, so an AdMob unit that still has Automatic refresh enabled cannot keep postponing CloudX's next first look - which it otherwise would, on every refresh. The demo's Google test units do refresh, so this path is live even here.

Auto-refresh itself stays off on the CloudX side: the pass cycle owns reloading, so an SDK refresh timer would compete with it and could swap the ad out from under the First Look source decision. CloudX banner auto-refresh is opt-out - showing a banner starts it unless the ad unit was first passed to StopBannerAutoRefresh - so the controller calls that before create and never calls StartBannerAutoRefresh. (GeneralScreen restarts refresh on focus; First Look deliberately does not.)

Disable automatic refresh on your AdMob banner ad unit.

This is the one step the code cannot do for you. The Google Mobile Ads Unity plugin has no refresh API: a BannerView loads 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 ad unit. If that setting is on, AdMob swaps the creative on its own schedule, outside the pass cycle. 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.

Google Mobile Ads dependency

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.

Using your own CloudX app

The demo ships with CloudX demo dashboard IDs so it runs without an account. To point it at your own CloudX app:

  1. Replace the app key and ad unit IDs in Assets/Scripts/DemoConfig.cs.
  2. 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 one (see the First Look section for why).

iOS target SDK

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.

About

CloudX Unity SDK

Resources

Stars

4 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages