fixed
This commit is contained in:
@@ -28,7 +28,12 @@ public class ColorbookFlowController : IAsyncStartable, IDisposable
|
|||||||
private IDisposable _selectedSub;
|
private IDisposable _selectedSub;
|
||||||
private IDisposable _returnToMainMenuSubscription;
|
private IDisposable _returnToMainMenuSubscription;
|
||||||
private bool _navigatingToGameplay;
|
private bool _navigatingToGameplay;
|
||||||
private int _selectCount;
|
// App-session counter, NOT instance state. ColorbookFlowController is scene-scoped: a fresh one
|
||||||
|
// is built every time the Colorbook scene loads, and selecting a drawing unloads the scene — so
|
||||||
|
// each visit makes exactly ONE selection. An instance counter would reset to 0 each visit, land
|
||||||
|
// on 1 (odd) every time, and the "% 2 == 0" show branch would NEVER fire. static persists across
|
||||||
|
// visits for the whole app run (resets on restart), matching the per-session interstitial cap.
|
||||||
|
private static int _selectCount;
|
||||||
private CancellationTokenSource _scopeCts;
|
private CancellationTokenSource _scopeCts;
|
||||||
|
|
||||||
public ColorbookFlowController(
|
public ColorbookFlowController(
|
||||||
@@ -65,15 +70,21 @@ public class ColorbookFlowController : IAsyncStartable, IDisposable
|
|||||||
|
|
||||||
if (!_navigatingToGameplay) _loadingScreen.Hide();
|
if (!_navigatingToGameplay) _loadingScreen.Hide();
|
||||||
|
|
||||||
PrewarmInterstitialAdAsync(ct).Forget();
|
PrewarmInterstitialAdAsync().Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async UniTaskVoid PrewarmInterstitialAdAsync(CancellationToken ct)
|
// Ad ops MUST NOT use the Colorbook scope token. This scene unloads inside HandleSelectionAsync —
|
||||||
|
// the same moment the interstitial should show — which disposes ColorBookLifetimeScope, calls our
|
||||||
|
// Dispose(), and cancels _scopeCts. A scope-bound load/show then aborts mid-flight (load: never
|
||||||
|
// ready; show: await throws OCE, handlers unsubscribed). AdMobAdService is the Boot/Root-scoped,
|
||||||
|
// app-lifetime singleton and self-manages teardown (_lifetimeCts + OnDestroy), so drive ad ops on
|
||||||
|
// CancellationToken.None — they intentionally outlive this scene.
|
||||||
|
private async UniTaskVoid PrewarmInterstitialAdAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!_ads.IsInitialized) await _ads.InitializeAsync(ct);
|
if (!_ads.IsInitialized) await _ads.InitializeAsync(CancellationToken.None);
|
||||||
if (!_ads.IsReady(AdFormat.Interstitial)) await _ads.LoadAsync(AdFormat.Interstitial, ct);
|
if (!_ads.IsReady(AdFormat.Interstitial)) await _ads.LoadAsync(AdFormat.Interstitial, CancellationToken.None);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -106,19 +117,18 @@ public class ColorbookFlowController : IAsyncStartable, IDisposable
|
|||||||
|
|
||||||
private async UniTaskVoid HandleSelectionAsync(string templateId)
|
private async UniTaskVoid HandleSelectionAsync(string templateId)
|
||||||
{
|
{
|
||||||
var ct = _scopeCts?.Token ?? CancellationToken.None;
|
|
||||||
|
|
||||||
_loadingScreen.Show();
|
_loadingScreen.Show();
|
||||||
_loadingScreen.SetProgress(0f);
|
_loadingScreen.SetProgress(0f);
|
||||||
|
|
||||||
// Frequency cap: show an interstitial on every 2nd level open (2nd, 4th, ...). On skip turns
|
// Frequency cap: show an interstitial on every 2nd level open (2nd, 4th, ...). On skip turns
|
||||||
// just keep one prewarmed so the next show has an ad ready. Fire-and-forget either way — the
|
// just keep one prewarmed so the next show has an ad ready. Fire-and-forget either way — the
|
||||||
// ad overlays the transition while the level loads underneath, so a missed/dropped ad callback
|
// ad overlays the transition while the level loads underneath, so a missed/dropped ad callback
|
||||||
// can't stall the flow at 0% anymore.
|
// can't stall the flow at 0% anymore. Ad ops run on CancellationToken.None, NOT the scene
|
||||||
|
// scope token: this scene unloads further down, which would otherwise cancel the show.
|
||||||
if (++_selectCount % 2 == 0)
|
if (++_selectCount % 2 == 0)
|
||||||
ShowInterstitialAdAsync(ct).Forget();
|
ShowInterstitialAdAsync().Forget();
|
||||||
else
|
else
|
||||||
PrewarmInterstitialAdAsync(ct).Forget();
|
PrewarmInterstitialAdAsync().Forget();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -143,7 +153,8 @@ public class ColorbookFlowController : IAsyncStartable, IDisposable
|
|||||||
// Fire-and-forget interstitial. Shows only if one is already prewarmed; otherwise it kicks a
|
// Fire-and-forget interstitial. Shows only if one is already prewarmed; otherwise it kicks a
|
||||||
// load for next time and returns immediately. Never blocks the level load — by design the
|
// load for next time and returns immediately. Never blocks the level load — by design the
|
||||||
// scene swap below does not depend on the ad's close callback, so the ad can never stall it.
|
// scene swap below does not depend on the ad's close callback, so the ad can never stall it.
|
||||||
private async UniTaskVoid ShowInterstitialAdAsync(CancellationToken ct)
|
// CancellationToken.None: the show must survive this scene's unload (see PrewarmInterstitialAdAsync).
|
||||||
|
private async UniTaskVoid ShowInterstitialAdAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -151,11 +162,11 @@ public class ColorbookFlowController : IAsyncStartable, IDisposable
|
|||||||
|
|
||||||
if (!_ads.IsReady(AdFormat.Interstitial))
|
if (!_ads.IsReady(AdFormat.Interstitial))
|
||||||
{
|
{
|
||||||
_ads.LoadAsync(AdFormat.Interstitial, ct).Forget();
|
_ads.LoadAsync(AdFormat.Interstitial, CancellationToken.None).Forget();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _ads.ShowAsync(AdFormat.Interstitial, ct);
|
await _ads.ShowAsync(AdFormat.Interstitial, CancellationToken.None);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -19,27 +19,40 @@ namespace Darkmatter.Services.Ads
|
|||||||
public class AdMobAdService : MonoBehaviour, IAdService
|
public class AdMobAdService : MonoBehaviour, IAdService
|
||||||
{
|
{
|
||||||
[SerializeField] private AdUnitCatalogSO catalog;
|
[SerializeField] private AdUnitCatalogSO catalog;
|
||||||
[Tooltip("Auto-reload after dismiss/failure for non-banner formats.")]
|
|
||||||
[SerializeField] private bool autoReload = true;
|
[Tooltip("Auto-reload after dismiss/failure for non-banner formats.")] [SerializeField]
|
||||||
[Tooltip("Seconds between auto-reload retries on failure.")]
|
private bool autoReload = true;
|
||||||
[SerializeField, Min(1f)] private float reloadDelaySeconds = 5f;
|
|
||||||
[Tooltip("Max reload attempts before giving up.")]
|
[Tooltip("Seconds between auto-reload retries on failure.")] [SerializeField, Min(1f)]
|
||||||
[SerializeField, Min(1)] private int reloadMaxAttempts = 6;
|
private float reloadDelaySeconds = 5f;
|
||||||
[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;
|
[Tooltip("Max reload attempts before giving up.")] [SerializeField, Min(1)]
|
||||||
[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.")]
|
private int reloadMaxAttempts = 6;
|
||||||
[SerializeField, Min(0)] private int maxInterstitialsPerSession = 8;
|
|
||||||
|
[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;
|
||||||
|
|
||||||
|
[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
|
// 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
|
// loaded ads across scene swaps), so this survives Colorbook<->Gameplay transitions and only
|
||||||
// resets on app restart — i.e. a true per-session cap.
|
// resets on app restart — i.e. a true per-session cap.
|
||||||
private int _interstitialsShownThisSession;
|
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.
|
||||||
private bool _isChildDirected = true;
|
private bool _isChildDirected = true;
|
||||||
@@ -165,6 +178,7 @@ namespace Darkmatter.Services.Ads
|
|||||||
SetState(format, AdLoadState.Failed);
|
SetState(format, AdLoadState.Failed);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
await UniTask.CompletedTask;
|
await UniTask.CompletedTask;
|
||||||
@@ -198,7 +212,7 @@ namespace Darkmatter.Services.Ads
|
|||||||
// Per-session interstitial cap. Check before load so a capped show wastes no fill. Skip
|
// 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.
|
// is silent (Failure, Shown=false); the fire-and-forget caller just keeps playing.
|
||||||
if (format == AdFormat.Interstitial && _interstitialsShownThisSession >= maxInterstitialsPerSession)
|
if (format == AdFormat.Interstitial && _interstitialsShownThisSession >= maxInterstitialsPerSession)
|
||||||
return AdShowResult.Failure("Session interstitial cap reached.");
|
return AdShowResult.Failure("[AdMobAdService] Session interstitial cap reached.");
|
||||||
|
|
||||||
if (!IsReady(format))
|
if (!IsReady(format))
|
||||||
{
|
{
|
||||||
@@ -206,6 +220,7 @@ namespace Darkmatter.Services.Ads
|
|||||||
if (!loaded) return AdShowResult.Failure($"{format} failed to load.");
|
if (!loaded) return AdShowResult.Failure($"{format} failed to load.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.Log($"[AdMobAdService] Showing {format} ad.");
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case AdFormat.Interstitial:
|
case AdFormat.Interstitial:
|
||||||
@@ -218,6 +233,7 @@ namespace Darkmatter.Services.Ads
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
return AdShowResult.Failure($"{format} not supported by ShowAsync.");
|
return AdShowResult.Failure($"{format} not supported by ShowAsync.");
|
||||||
#else
|
#else
|
||||||
await UniTask.CompletedTask;
|
await UniTask.CompletedTask;
|
||||||
@@ -225,7 +241,8 @@ namespace Darkmatter.Services.Ads
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public async UniTask<bool> ShowBannerAsync(BannerSize size, BannerPosition position, CancellationToken cancellationToken)
|
public async UniTask<bool> ShowBannerAsync(BannerSize size, BannerPosition position,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (!_initialized) return false;
|
if (!_initialized) return false;
|
||||||
|
|
||||||
@@ -309,7 +326,8 @@ namespace Darkmatter.Services.Ads
|
|||||||
MobileAds.SetRequestConfiguration(config);
|
MobileAds.SetRequestConfiguration(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async UniTask<bool> LoadInterstitialAsync(string unitId, AdRequest request, CancellationToken cancellationToken)
|
private async UniTask<bool> LoadInterstitialAsync(string unitId, AdRequest request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tcs = new UniTaskCompletionSource<bool>();
|
var tcs = new UniTaskCompletionSource<bool>();
|
||||||
InterstitialAd.Load(unitId, request, (ad, error) =>
|
InterstitialAd.Load(unitId, request, (ad, error) =>
|
||||||
@@ -320,6 +338,7 @@ namespace Darkmatter.Services.Ads
|
|||||||
tcs.TrySetResult(false);
|
tcs.TrySetResult(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_interstitial?.Destroy();
|
_interstitial?.Destroy();
|
||||||
_interstitial = ad;
|
_interstitial = ad;
|
||||||
WireFullScreenEvents(ad, AdFormat.Interstitial);
|
WireFullScreenEvents(ad, AdFormat.Interstitial);
|
||||||
@@ -334,7 +353,8 @@ namespace Darkmatter.Services.Ads
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async UniTask<bool> LoadRewardedAsync(string unitId, AdRequest request, CancellationToken cancellationToken)
|
private async UniTask<bool> LoadRewardedAsync(string unitId, AdRequest request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tcs = new UniTaskCompletionSource<bool>();
|
var tcs = new UniTaskCompletionSource<bool>();
|
||||||
RewardedAd.Load(unitId, request, (ad, error) =>
|
RewardedAd.Load(unitId, request, (ad, error) =>
|
||||||
@@ -345,6 +365,7 @@ namespace Darkmatter.Services.Ads
|
|||||||
tcs.TrySetResult(false);
|
tcs.TrySetResult(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_rewarded?.Destroy();
|
_rewarded?.Destroy();
|
||||||
_rewarded = ad;
|
_rewarded = ad;
|
||||||
WireFullScreenEvents(ad, AdFormat.Rewarded);
|
WireFullScreenEvents(ad, AdFormat.Rewarded);
|
||||||
@@ -359,7 +380,8 @@ namespace Darkmatter.Services.Ads
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async UniTask<bool> LoadRewardedInterstitialAsync(string unitId, AdRequest request, CancellationToken cancellationToken)
|
private async UniTask<bool> LoadRewardedInterstitialAsync(string unitId, AdRequest request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tcs = new UniTaskCompletionSource<bool>();
|
var tcs = new UniTaskCompletionSource<bool>();
|
||||||
RewardedInterstitialAd.Load(unitId, request, (ad, error) =>
|
RewardedInterstitialAd.Load(unitId, request, (ad, error) =>
|
||||||
@@ -370,6 +392,7 @@ namespace Darkmatter.Services.Ads
|
|||||||
tcs.TrySetResult(false);
|
tcs.TrySetResult(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_rewardedInterstitial?.Destroy();
|
_rewardedInterstitial?.Destroy();
|
||||||
_rewardedInterstitial = ad;
|
_rewardedInterstitial = ad;
|
||||||
WireFullScreenEvents(ad, AdFormat.RewardedInterstitial);
|
WireFullScreenEvents(ad, AdFormat.RewardedInterstitial);
|
||||||
@@ -384,7 +407,8 @@ namespace Darkmatter.Services.Ads
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async UniTask<bool> LoadAppOpenAsync(string unitId, AdRequest request, CancellationToken cancellationToken)
|
private async UniTask<bool> LoadAppOpenAsync(string unitId, AdRequest request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tcs = new UniTaskCompletionSource<bool>();
|
var tcs = new UniTaskCompletionSource<bool>();
|
||||||
AppOpenAd.Load(unitId, request, (ad, error) =>
|
AppOpenAd.Load(unitId, request, (ad, error) =>
|
||||||
@@ -395,6 +419,7 @@ namespace Darkmatter.Services.Ads
|
|||||||
tcs.TrySetResult(false);
|
tcs.TrySetResult(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_appOpen?.Destroy();
|
_appOpen?.Destroy();
|
||||||
_appOpen = ad;
|
_appOpen = ad;
|
||||||
WireFullScreenEvents(ad, AdFormat.AppOpen);
|
WireFullScreenEvents(ad, AdFormat.AppOpen);
|
||||||
@@ -513,8 +538,16 @@ namespace Darkmatter.Services.Ads
|
|||||||
var tcs = new UniTaskCompletionSource<AdShowResult>();
|
var tcs = new UniTaskCompletionSource<AdShowResult>();
|
||||||
bool resolved = false;
|
bool resolved = false;
|
||||||
|
|
||||||
Action onClosed = () => { resolved = true; tcs.TrySetResult(buildResult()); };
|
Action onClosed = () =>
|
||||||
Action<AdError> onFailed = err => { resolved = true; tcs.TrySetResult(AdShowResult.Failure(err?.GetMessage())); };
|
{
|
||||||
|
resolved = true;
|
||||||
|
tcs.TrySetResult(buildResult());
|
||||||
|
};
|
||||||
|
Action<AdError> onFailed = err =>
|
||||||
|
{
|
||||||
|
resolved = true;
|
||||||
|
tcs.TrySetResult(AdShowResult.Failure(err?.GetMessage()));
|
||||||
|
};
|
||||||
|
|
||||||
subscribe(onClosed, onFailed);
|
subscribe(onClosed, onFailed);
|
||||||
show();
|
show();
|
||||||
@@ -570,21 +603,26 @@ namespace Darkmatter.Services.Ads
|
|||||||
{
|
{
|
||||||
// App returned to foreground after the ad held it => ad was dismissed but
|
// App returned to foreground after the ad held it => ad was dismissed but
|
||||||
// the close callback was dropped. Brief grace for the real event, then force.
|
// the close callback was dropped. Brief grace for the real event, then force.
|
||||||
await UniTask.Delay(ForegroundGraceMs, DelayType.Realtime, PlayerLoopTiming.Update, cancellationToken);
|
await UniTask.Delay(ForegroundGraceMs, DelayType.Realtime, PlayerLoopTiming.Update,
|
||||||
|
cancellationToken);
|
||||||
if (!isResolved() && tcs.TrySetResult(buildResult()))
|
if (!isResolved() && tcs.TrySetResult(buildResult()))
|
||||||
Debug.LogWarning("[AdMobAdService] Close callback missed; recovered via foreground watchdog.");
|
Debug.LogWarning(
|
||||||
|
"[AdMobAdService] Close callback missed; recovered via foreground watchdog.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elapsed >= showWatchdogSeconds)
|
if (elapsed >= showWatchdogSeconds)
|
||||||
{
|
{
|
||||||
if (!isResolved() && tcs.TrySetResult(buildResult()))
|
if (!isResolved() && tcs.TrySetResult(buildResult()))
|
||||||
Debug.LogWarning($"[AdMobAdService] Close callback missed; recovered via {showWatchdogSeconds:0}s watchdog cap.");
|
Debug.LogWarning(
|
||||||
|
$"[AdMobAdService] Close callback missed; recovered via {showWatchdogSeconds:0}s watchdog cap.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException) { }
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WireFullScreenEvents(InterstitialAd ad, AdFormat format)
|
private void WireFullScreenEvents(InterstitialAd ad, AdFormat format)
|
||||||
@@ -658,9 +696,12 @@ namespace Darkmatter.Services.Ads
|
|||||||
if (IsReady(format)) return;
|
if (IsReady(format)) return;
|
||||||
if (await LoadAsync(format, cancellationToken)) return;
|
if (await LoadAsync(format, cancellationToken)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.LogWarning($"[AdMobAdService] {format} reload gave up after {reloadMaxAttempts} attempts.");
|
Debug.LogWarning($"[AdMobAdService] {format} reload gave up after {reloadMaxAttempts} attempts.");
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException) { }
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AdSize MapBannerSize(BannerSize size) => size switch
|
private static AdSize MapBannerSize(BannerSize size) => size switch
|
||||||
@@ -671,7 +712,8 @@ namespace Darkmatter.Services.Ads
|
|||||||
BannerSize.FullBanner => AdSize.IABBanner,
|
BannerSize.FullBanner => AdSize.IABBanner,
|
||||||
BannerSize.Leaderboard => AdSize.Leaderboard,
|
BannerSize.Leaderboard => AdSize.Leaderboard,
|
||||||
BannerSize.SmartBanner => AdSize.SmartBanner,
|
BannerSize.SmartBanner => AdSize.SmartBanner,
|
||||||
BannerSize.AnchoredAdaptive => AdSize.GetCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(AdSize.FullWidth),
|
BannerSize.AnchoredAdaptive => AdSize.GetCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(
|
||||||
|
AdSize.FullWidth),
|
||||||
_ => AdSize.Banner
|
_ => AdSize.Banner
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -694,4 +736,4 @@ namespace Darkmatter.Services.Ads
|
|||||||
LoadStateChanged?.Invoke(format, state);
|
LoadStateChanged?.Invoke(format, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><resources><string name="com.crashlytics.android.build_id" translatable="false">0a4c6c8f-8290-4f0a-8af5-899267e3f184</string></resources>
|
<?xml version="1.0" encoding="utf-8"?><resources><string name="com.crashlytics.android.build_id" translatable="false">ed36bb40-e40f-4cbd-95e3-d76e98ede383</string></resources>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ MonoBehaviour:
|
|||||||
m_ExportAsGoogleAndroidProject: 0
|
m_ExportAsGoogleAndroidProject: 0
|
||||||
m_DebugSymbolLevel: 4
|
m_DebugSymbolLevel: 4
|
||||||
m_DebugSymbolFormat: 5
|
m_DebugSymbolFormat: 5
|
||||||
m_CurrentDeploymentTargetId: KBUKQ4PNCAOBS8YH
|
m_CurrentDeploymentTargetId: __builtin__target_default
|
||||||
m_BuildType: 2
|
m_BuildType: 2
|
||||||
m_LinkTimeOptimization: 0
|
m_LinkTimeOptimization: 0
|
||||||
m_BuildAppBundle: 1
|
m_BuildAppBundle: 1
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ PlayerSettings:
|
|||||||
iPhone: 1
|
iPhone: 1
|
||||||
tvOS: 0
|
tvOS: 0
|
||||||
overrideDefaultApplicationIdentifier: 1
|
overrideDefaultApplicationIdentifier: 1
|
||||||
AndroidBundleVersionCode: 6
|
AndroidBundleVersionCode: 7
|
||||||
AndroidMinSdkVersion: 25
|
AndroidMinSdkVersion: 25
|
||||||
AndroidTargetSdkVersion: 0
|
AndroidTargetSdkVersion: 0
|
||||||
AndroidPreferredInstallLocation: 1
|
AndroidPreferredInstallLocation: 1
|
||||||
|
|||||||
Reference in New Issue
Block a user