Skip to content

Ads (Unity)

FRVRSDK.Ad exposes three ad surfaces:

  • Interstitial — non‑opt‑in, full‑screen break.
  • Rewarded — player opts in, gets something when they finish watching.
  • Banner — persistent overlay served by the host channel.

Interstitial and reward calls are callback‑based (start / error / finish). The error callback receives an SdkError struct — error.error is the message string. Make sure you’ve imported using FRVR; so the SdkError type and the FRVRSDK static class resolve.

FRVRSDK.Ad.ShowInterstitialAd(
    () => Debug.Log("Interstitial started"),
    (SdkError error) => Debug.Log("Interstitial error: " + error.error),
    () => Debug.Log("Interstitial finished"));

onFinish fires whether the user watched to the end or dismissed partway — it just signals the ad view ended. There’s no concept of “completed vs. delivered” for interstitials.

FRVRSDK.Ad.ShowRewardAd(
    () => Debug.Log("Reward started"),
    (SdkError error) => Debug.Log("Reward error: " + error.error),
    () => GiveExtraLife());   // called only on successful completion

onFinish fires only when the user completed the ad (watched it through). If they skipped, closed, or the ad failed to render, the error callback fires instead — you do not hand out the reward.

Synchronous check for whether the network has fill for the given ad type. Pass "interstitial" or "reward".

if (FRVRSDK.Ad.IsAdReady("reward"))
{
    doubleRewardButton.interactable = true;
}

In Editor simulation IsAdReady always returns true.

The banner surface is host‑provided and lifecycle is simpler — there are no onStart / onError callbacks, just a completion bool indicating whether the banner was shown successfully.

FRVRSDK.Ad.ShowBannerAd(success =>
{
    if (!success) Debug.Log("Banner unavailable on this channel");
});

// later — when entering a screen that mustn't be covered
FRVRSDK.Ad.HideBannerAd();

Banner support varies wildly between channels; treat success == false as the normal case for many host platforms and just hide your placeholder.

Typical pattern: “Watch ad for 2× coins”

Section titled “Typical pattern: “Watch ad for 2× coins””
void OnDoubleRewardButtonPressed()
{
    doubleRewardButton.interactable = false;

    FRVRSDK.Ad.ShowRewardAd(
        () => { /* mute game audio, pause gameplay */ },
        (SdkError err) => {
            doubleRewardButton.interactable = true;
            ShowToast("Ad unavailable right now");
        },
        () => {
            currentRunCoins *= 2;
            ShowToast("Rewarded!");
        });
}

While an ad is showing, the Unity SDK ignores any second ShowInterstitialAd / ShowRewardAd call until the current one resolves (it’s tracked by an internal _adRequestInProgress flag).

Interstitial throttling lives in the underlying Web SDK, not the Unity wrapper — the Unity layer just forwards the request and reports back whatever the JS layer returns. In practice the Web SDK enforces a minimum interval between interstitials and blocks the first ~100 seconds after init, so an onError shortly after init usually means “not yet”.

Rewarded ads are not throttled — they fire on demand.

The Unity wrapper does not auto-pause the game loop or auto-mute audio when an ad opens. Unity gets OnApplicationFocus(false) from the browser when the ad iframe takes over, which freezes Update while the tab is hidden — but if you have music playing through AudioListener, you have to silence it yourself. The cleanest place is the onStart callback (FRVRSDK.MuteVolume()), with FRVRSDK.UnmuteVolume() in onFinish / onError. See Lifecycle (Unity).