Intersterial Limit added
This commit is contained in:
@@ -27,12 +27,18 @@ namespace Darkmatter.Services.Ads
|
|||||||
[SerializeField, Min(1)] private int reloadMaxAttempts = 6;
|
[SerializeField, Min(1)] private int reloadMaxAttempts = 6;
|
||||||
[Tooltip("Hard fallback (seconds) to recover a full-screen show if AdMob never raises its close callback. Android focus-return recovery usually fires far sooner; this cap covers iOS/edge cases. Must exceed max plausible ad length so a real ad is never cut short.")]
|
[Tooltip("Hard fallback (seconds) to recover a full-screen show if AdMob never raises its close callback. Android focus-return recovery usually fires far sooner; this cap covers iOS/edge cases. Must exceed max plausible ad length so a real ad is never cut short.")]
|
||||||
[SerializeField, Min(15f)] private float showWatchdogSeconds = 60f;
|
[SerializeField, Min(15f)] private float showWatchdogSeconds = 60f;
|
||||||
|
[Tooltip("Max interstitials shown per app session (run). Once reached, ShowAsync(Interstitial) no-ops until the app restarts. Counts only ads actually shown, not failed/skipped attempts. 0 disables interstitials.")]
|
||||||
|
[SerializeField, Min(0)] private int maxInterstitialsPerSession = 8;
|
||||||
|
|
||||||
public bool IsInitialized => _initialized;
|
public bool IsInitialized => _initialized;
|
||||||
public event Action<AdFormat, AdLoadState> LoadStateChanged;
|
public event Action<AdFormat, AdLoadState> LoadStateChanged;
|
||||||
|
|
||||||
private IAnalyticsService _analytics;
|
private IAnalyticsService _analytics;
|
||||||
private bool _initialized;
|
private bool _initialized;
|
||||||
|
// Per-session interstitial counter. The service is the app-lifetime singleton (it retains
|
||||||
|
// loaded ads across scene swaps), so this survives Colorbook<->Gameplay transitions and only
|
||||||
|
// resets on app restart — i.e. a true per-session cap.
|
||||||
|
private int _interstitialsShownThisSession;
|
||||||
private bool _hasUserConsent = true;
|
private bool _hasUserConsent = true;
|
||||||
// Coloring book is a child-directed app, so default to true. SetConsent can still
|
// Coloring book is a child-directed app, so default to true. SetConsent can still
|
||||||
// override if a consent flow later supplies a different value.
|
// override if a consent flow later supplies a different value.
|
||||||
@@ -189,6 +195,11 @@ namespace Darkmatter.Services.Ads
|
|||||||
if (!_initialized) return AdShowResult.Failure("Not initialized.");
|
if (!_initialized) return AdShowResult.Failure("Not initialized.");
|
||||||
|
|
||||||
#if GOOGLE_MOBILE_ADS
|
#if GOOGLE_MOBILE_ADS
|
||||||
|
// Per-session interstitial cap. Check before load so a capped show wastes no fill. Skip
|
||||||
|
// is silent (Failure, Shown=false); the fire-and-forget caller just keeps playing.
|
||||||
|
if (format == AdFormat.Interstitial && _interstitialsShownThisSession >= maxInterstitialsPerSession)
|
||||||
|
return AdShowResult.Failure("Session interstitial cap reached.");
|
||||||
|
|
||||||
if (!IsReady(format))
|
if (!IsReady(format))
|
||||||
{
|
{
|
||||||
bool loaded = await LoadAsync(format, cancellationToken);
|
bool loaded = await LoadAsync(format, cancellationToken);
|
||||||
@@ -197,7 +208,12 @@ namespace Darkmatter.Services.Ads
|
|||||||
|
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case AdFormat.Interstitial: return await ShowInterstitialAsync(cancellationToken);
|
case AdFormat.Interstitial:
|
||||||
|
{
|
||||||
|
var result = await ShowInterstitialAsync(cancellationToken);
|
||||||
|
if (result.Shown) _interstitialsShownThisSession++; // count real shows only
|
||||||
|
return result;
|
||||||
|
}
|
||||||
case AdFormat.Rewarded: return await ShowRewardedAsync(cancellationToken);
|
case AdFormat.Rewarded: return await ShowRewardedAsync(cancellationToken);
|
||||||
case AdFormat.RewardedInterstitial: return await ShowRewardedInterstitialAsync(cancellationToken);
|
case AdFormat.RewardedInterstitial: return await ShowRewardedInterstitialAsync(cancellationToken);
|
||||||
case AdFormat.AppOpen: return await ShowAppOpenAsync(cancellationToken);
|
case AdFormat.AppOpen: return await ShowAppOpenAsync(cancellationToken);
|
||||||
|
|||||||
Reference in New Issue
Block a user