From 705d6b482593d30af41f2747c9e0c683b34ef073 Mon Sep 17 00:00:00 2001 From: Savya Bikram Shah Date: Mon, 1 Jun 2026 16:52:00 +0545 Subject: [PATCH] fixes --- .../System/ColorbookFlowController.cs | 67 ++- .../Services/Ads/Systems/AdMobAdService.cs | 239 +++++--- .../ColoringPrefabs/BallColoring.prefab | 568 +++++++++++++++++- .../Data/Drawings/Templates/Ball.asset | 16 +- 4 files changed, 764 insertions(+), 126 deletions(-) diff --git a/Assets/Darkmatter/Code/Features/ColorbookFlow/System/ColorbookFlowController.cs b/Assets/Darkmatter/Code/Features/ColorbookFlow/System/ColorbookFlowController.cs index 6b566d9..2106d02 100644 --- a/Assets/Darkmatter/Code/Features/ColorbookFlow/System/ColorbookFlowController.cs +++ b/Assets/Darkmatter/Code/Features/ColorbookFlow/System/ColorbookFlowController.cs @@ -55,20 +55,20 @@ public class ColorbookFlowController : IAsyncStartable, IDisposable await _drawingCatalog.InitializeAsync(cancellation); if (!_navigatingToGameplay) _loadingScreen.Hide(); - PrewarmRewardedAdAsync(_scopeCts.Token).Forget(); + PrewarmInterstitialAdAsync(_scopeCts.Token).Forget(); } - private async UniTaskVoid PrewarmRewardedAdAsync(CancellationToken ct) + private async UniTaskVoid PrewarmInterstitialAdAsync(CancellationToken ct) { try { if (!_ads.IsInitialized) await _ads.InitializeAsync(ct); - if (!_ads.IsReady(AdFormat.Rewarded)) await _ads.LoadAsync(AdFormat.Rewarded, ct); + if (!_ads.IsReady(AdFormat.Interstitial)) await _ads.LoadAsync(AdFormat.Interstitial, ct); } catch (OperationCanceledException) { } catch (Exception ex) { - UnityEngine.Debug.LogWarning($"[ColorbookFlow] Rewarded prewarm failed: {ex.Message}"); + UnityEngine.Debug.LogWarning($"[ColorbookFlow] Interstitial prewarm failed: {ex.Message}"); } } @@ -101,40 +101,51 @@ public class ColorbookFlowController : IAsyncStartable, IDisposable _loadingScreen.Show(); _loadingScreen.SetProgress(0f); - await ShowRewardedAdAsync(ct); + // Fire the interstitial but never await it: the ad overlays the transition while the level + // loads underneath, so a missed/dropped ad callback can't stall the flow at 0% anymore. + ShowInterstitialAdAsync(ct).Forget(); - // Ad SDKs can resume the continuation on a background thread; the scene load below - // must run on the Unity main thread. No-op when already there. - await UniTask.SwitchToMainThread(ct); - - var progress = new Progress(p => _loadingScreen.SetProgress(p * 0.5f)); - var mappedProgress = new Progress(p => _loadingScreen.SetProgress(0.5f + p * 0.25f)); - await _progression.SetLastOpenedAsync(templateId); - await _scenes.LoadSceneAsync(nameof(GameScene.Gameplay), progress: progress, cancellationToken: default); - await _scenes.UnloadSceneAsync(nameof(GameScene.Colorbook), progress: mappedProgress, - cancellationToken: default); - } - - private async UniTask ShowRewardedAdAsync(CancellationToken ct) - { - const int InitTimeoutMs = 4000; try { - if (!_ads.IsInitialized) + var progress = new Progress(p => _loadingScreen.SetProgress(p * 0.5f)); + var mappedProgress = new Progress(p => _loadingScreen.SetProgress(0.5f + p * 0.25f)); + await _progression.SetLastOpenedAsync(templateId); + await _scenes.LoadSceneAsync(nameof(GameScene.Gameplay), progress: progress, cancellationToken: default); + await _scenes.UnloadSceneAsync(nameof(GameScene.Colorbook), progress: mappedProgress, + cancellationToken: default); + } + catch (OperationCanceledException) { /* scope disposed */ } + catch (Exception ex) + { + // Navigation failed mid-flight: release the latch and drop the loading screen so the + // user can retry instead of being stuck on a loader frozen at 0%. + UnityEngine.Debug.LogException(ex); + _navigatingToGameplay = false; + _loadingScreen.Hide(); + } + } + + // 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 + // 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) + { + try + { + if (!_ads.IsInitialized) return; + + if (!_ads.IsReady(AdFormat.Interstitial)) { - using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(ct); - timeoutCts.CancelAfter(InitTimeoutMs); - await _ads.InitializeAsync(timeoutCts.Token); + _ads.LoadAsync(AdFormat.Interstitial, ct).Forget(); + return; } - if (!_ads.IsReady(AdFormat.Rewarded)) return; - - await _ads.ShowAsync(AdFormat.Rewarded, ct); + await _ads.ShowAsync(AdFormat.Interstitial, ct); } catch (OperationCanceledException) { } catch (Exception ex) { - UnityEngine.Debug.LogWarning($"[ColorbookFlow] Rewarded ad skipped: {ex.Message}"); + UnityEngine.Debug.LogWarning($"[ColorbookFlow] Interstitial skipped: {ex.Message}"); } } diff --git a/Assets/Darkmatter/Code/Services/Ads/Systems/AdMobAdService.cs b/Assets/Darkmatter/Code/Services/Ads/Systems/AdMobAdService.cs index ea5074c..7cf206f 100644 --- a/Assets/Darkmatter/Code/Services/Ads/Systems/AdMobAdService.cs +++ b/Assets/Darkmatter/Code/Services/Ads/Systems/AdMobAdService.cs @@ -23,6 +23,8 @@ namespace Darkmatter.Services.Ads [SerializeField, Min(1f)] private float reloadDelaySeconds = 5f; [Tooltip("Max reload attempts before giving up.")] [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.")] + [SerializeField, Min(15f)] private float showWatchdogSeconds = 60f; public bool IsInitialized => _initialized; public event Action LoadStateChanged; @@ -32,6 +34,13 @@ namespace Darkmatter.Services.Ads private bool _isChildDirected; private CancellationTokenSource _lifetimeCts; + // App interruption state, fed by the Unity lifecycle messages below. A full-screen ad + // pushes the app into this state (Android raises focus-loss, iOS raises pause); the + // watchdog uses the return-to-foreground transition to recover a missed close callback. + private bool _appPaused; + private bool _appUnfocused; + private bool AppInterrupted => _appPaused || _appUnfocused; + private readonly Dictionary _states = new(); #if GOOGLE_MOBILE_ADS @@ -64,6 +73,11 @@ namespace Darkmatter.Services.Ads #endif } + // Android raises focus-loss for full-screen ads; iOS raises pause. Track both so the show + // watchdog can detect the ad's return-to-foreground regardless of platform. + private void OnApplicationPause(bool pauseStatus) => _appPaused = pauseStatus; + private void OnApplicationFocus(bool hasFocus) => _appUnfocused = !hasFocus; + public async UniTask InitializeAsync(CancellationToken cancellationToken) { if (_initialized) return; @@ -364,81 +378,116 @@ namespace Darkmatter.Services.Ads } } - private async UniTask ShowInterstitialAsync(CancellationToken cancellationToken) - { - var tcs = new UniTaskCompletionSource(); - Action onClosed = () => tcs.TrySetResult(AdShowResult.Success()); - Action onFailed = err => tcs.TrySetResult(AdShowResult.Failure(err?.GetMessage())); - - _interstitial.OnAdFullScreenContentClosed += onClosed; - _interstitial.OnAdFullScreenContentFailed += onFailed; - _interstitial.Show(); - - try - { - using (cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken))) - return await tcs.Task; - } - finally - { - if (_interstitial != null) + private UniTask ShowInterstitialAsync(CancellationToken cancellationToken) => + ShowFullScreenAsync( + AdFormat.Interstitial, + (c, f) => { - _interstitial.OnAdFullScreenContentClosed -= onClosed; - _interstitial.OnAdFullScreenContentFailed -= onFailed; - } - ScheduleReload(AdFormat.Interstitial); - } - } + _interstitial.OnAdFullScreenContentClosed += c; + _interstitial.OnAdFullScreenContentFailed += f; + }, + (c, f) => + { + if (_interstitial == null) return; + _interstitial.OnAdFullScreenContentClosed -= c; + _interstitial.OnAdFullScreenContentFailed -= f; + }, + () => AdShowResult.Success(), + () => _interstitial.Show(), + cancellationToken); - private async UniTask ShowRewardedAsync(CancellationToken cancellationToken) + private UniTask ShowRewardedAsync(CancellationToken cancellationToken) { - var tcs = new UniTaskCompletionSource(); bool earned = false; AdReward reward = default; - - Action onClosed = () => tcs.TrySetResult(earned ? AdShowResult.WithReward(reward) : AdShowResult.Success()); - Action onFailed = err => tcs.TrySetResult(AdShowResult.Failure(err?.GetMessage())); - - _rewarded.OnAdFullScreenContentClosed += onClosed; - _rewarded.OnAdFullScreenContentFailed += onFailed; - _rewarded.Show(r => - { - earned = true; - reward = new AdReward(r.Type, r.Amount); - }); - - try - { - using (cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken))) - return await tcs.Task; - } - finally - { - if (_rewarded != null) + return ShowFullScreenAsync( + AdFormat.Rewarded, + (c, f) => { - _rewarded.OnAdFullScreenContentClosed -= onClosed; - _rewarded.OnAdFullScreenContentFailed -= onFailed; - } - ScheduleReload(AdFormat.Rewarded); - } + _rewarded.OnAdFullScreenContentClosed += c; + _rewarded.OnAdFullScreenContentFailed += f; + }, + (c, f) => + { + if (_rewarded == null) return; + _rewarded.OnAdFullScreenContentClosed -= c; + _rewarded.OnAdFullScreenContentFailed -= f; + }, + () => earned ? AdShowResult.WithReward(reward) : AdShowResult.Success(), + () => _rewarded.Show(r => + { + earned = true; + reward = new AdReward(r.Type, r.Amount); + }), + cancellationToken); } - private async UniTask ShowRewardedInterstitialAsync(CancellationToken cancellationToken) + private UniTask ShowRewardedInterstitialAsync(CancellationToken cancellationToken) { - var tcs = new UniTaskCompletionSource(); bool earned = false; AdReward reward = default; + return ShowFullScreenAsync( + AdFormat.RewardedInterstitial, + (c, f) => + { + _rewardedInterstitial.OnAdFullScreenContentClosed += c; + _rewardedInterstitial.OnAdFullScreenContentFailed += f; + }, + (c, f) => + { + if (_rewardedInterstitial == null) return; + _rewardedInterstitial.OnAdFullScreenContentClosed -= c; + _rewardedInterstitial.OnAdFullScreenContentFailed -= f; + }, + () => earned ? AdShowResult.WithReward(reward) : AdShowResult.Success(), + () => _rewardedInterstitial.Show(r => + { + earned = true; + reward = new AdReward(r.Type, r.Amount); + }), + cancellationToken); + } - Action onClosed = () => tcs.TrySetResult(earned ? AdShowResult.WithReward(reward) : AdShowResult.Success()); - Action onFailed = err => tcs.TrySetResult(AdShowResult.Failure(err?.GetMessage())); + private UniTask ShowAppOpenAsync(CancellationToken cancellationToken) => + ShowFullScreenAsync( + AdFormat.AppOpen, + (c, f) => + { + _appOpen.OnAdFullScreenContentClosed += c; + _appOpen.OnAdFullScreenContentFailed += f; + }, + (c, f) => + { + if (_appOpen == null) return; + _appOpen.OnAdFullScreenContentClosed -= c; + _appOpen.OnAdFullScreenContentFailed -= f; + }, + () => AdShowResult.Success(), + () => _appOpen.Show(), + cancellationToken); - _rewardedInterstitial.OnAdFullScreenContentClosed += onClosed; - _rewardedInterstitial.OnAdFullScreenContentFailed += onFailed; - _rewardedInterstitial.Show(r => - { - earned = true; - reward = new AdReward(r.Type, r.Amount); - }); + // Shared full-screen show flow. AdMob can drop OnAdFullScreenContentClosed for a shown ad + // (focus loss/regain mid-ad, reloaded-ad reuse on a 2nd show, SDK edge cases); without a + // fallback the awaiting caller hangs forever and the post-ad scene load never runs (loading + // bar frozen at 0%). WatchShowAsync force-resolves via idempotent TrySetResult if the real + // close event never arrives. buildResult is reused so a granted reward survives recovery. + private async UniTask ShowFullScreenAsync( + AdFormat format, + Action> subscribe, + Action> unsubscribe, + Func buildResult, + Action show, + CancellationToken cancellationToken) + { + var tcs = new UniTaskCompletionSource(); + bool resolved = false; + + Action onClosed = () => { resolved = true; tcs.TrySetResult(buildResult()); }; + Action onFailed = err => { resolved = true; tcs.TrySetResult(AdShowResult.Failure(err?.GetMessage())); }; + + subscribe(onClosed, onFailed); + show(); + WatchShowAsync(tcs, () => resolved, buildResult, cancellationToken).Forget(); try { @@ -447,39 +496,59 @@ namespace Darkmatter.Services.Ads } finally { - if (_rewardedInterstitial != null) - { - _rewardedInterstitial.OnAdFullScreenContentClosed -= onClosed; - _rewardedInterstitial.OnAdFullScreenContentFailed -= onFailed; - } - ScheduleReload(AdFormat.RewardedInterstitial); + resolved = true; // stop the watchdog within one poll + unsubscribe(onClosed, onFailed); + ScheduleReload(format); } } - private async UniTask ShowAppOpenAsync(CancellationToken cancellationToken) + // Recovers a full-screen show when AdMob never raises its close callback. Primary signal: + // the ad interrupts the app (focus-loss on Android, pause on iOS) and then the app returns + // to the foreground — independent of OnAdFullScreenContentOpened, which can also be dropped. + // Fallback: a hard time cap for platforms/cases where neither lifecycle event fires. + // Realtime delays so a paused game (timeScale = 0) can't freeze the watchdog. + private async UniTaskVoid WatchShowAsync( + UniTaskCompletionSource tcs, + Func isResolved, + Func buildResult, + CancellationToken cancellationToken) { - var tcs = new UniTaskCompletionSource(); - Action onClosed = () => tcs.TrySetResult(AdShowResult.Success()); - Action onFailed = err => tcs.TrySetResult(AdShowResult.Failure(err?.GetMessage())); - - _appOpen.OnAdFullScreenContentClosed += onClosed; - _appOpen.OnAdFullScreenContentFailed += onFailed; - _appOpen.Show(); + const int PollMs = 250; + const int ForegroundGraceMs = 750; + bool sawInterrupted = false; + float elapsed = 0f; try { - using (cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken))) - return await tcs.Task; - } - finally - { - if (_appOpen != null) + while (!cancellationToken.IsCancellationRequested && !isResolved()) { - _appOpen.OnAdFullScreenContentClosed -= onClosed; - _appOpen.OnAdFullScreenContentFailed -= onFailed; + await UniTask.Delay(PollMs, DelayType.Realtime, PlayerLoopTiming.Update, cancellationToken); + if (isResolved()) return; + elapsed += PollMs / 1000f; + + if (AppInterrupted) + { + sawInterrupted = true; // ad took the foreground + } + else if (sawInterrupted) + { + // 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. + await UniTask.Delay(ForegroundGraceMs, DelayType.Realtime, PlayerLoopTiming.Update, cancellationToken); + if (!isResolved() && tcs.TrySetResult(buildResult())) + Debug.LogWarning("[AdMobAdService] Close callback missed; recovered via foreground watchdog."); + return; + } + + if (elapsed >= showWatchdogSeconds) + { + if (!isResolved() && tcs.TrySetResult(buildResult())) + Debug.LogWarning($"[AdMobAdService] Close callback missed; recovered via {showWatchdogSeconds:0}s watchdog cap."); + return; + } } - ScheduleReload(AdFormat.AppOpen); } + catch (OperationCanceledException) { } } private void WireFullScreenEvents(InterstitialAd ad, AdFormat format) => diff --git a/Assets/Darkmatter/Content/Colorbook UI/Prefabs/ColoringPrefabs/BallColoring.prefab b/Assets/Darkmatter/Content/Colorbook UI/Prefabs/ColoringPrefabs/BallColoring.prefab index 838c9b1..34cf395 100644 --- a/Assets/Darkmatter/Content/Colorbook UI/Prefabs/ColoringPrefabs/BallColoring.prefab +++ b/Assets/Darkmatter/Content/Colorbook UI/Prefabs/ColoringPrefabs/BallColoring.prefab @@ -1,5 +1,365 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1 &2062124670924785838 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4283726034190383322} + - component: {fileID: 3056456366338868420} + - component: {fileID: 4472768584405535780} + - component: {fileID: 1416192098695008161} + m_Layer: 5 + m_Name: Ball 1 (4) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4283726034190383322 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2062124670924785838} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 2.1480439, y: 2.1480439, z: 2.1480439} + m_ConstrainProportionsScale: 1 + m_Children: [] + m_Father: {fileID: 7007843749351456914} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 120, y: -63} + m_SizeDelta: {x: 206, y: 160} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3056456366338868420 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2062124670924785838} + m_CullTransparentMesh: 1 +--- !u!114 &4472768584405535780 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2062124670924785838} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 782004218, guid: 6d69a607d0df04148bf50bc6ef2d6fcc, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &1416192098695008161 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2062124670924785838} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7667901d8aea645d28b5125a2ed546ce, type: 3} + m_Name: + m_EditorClassIdentifier: Features.Coloring::Darkmatter.Features.Coloring.UI.ColorRegionView + k__BackingField: Ball_1__4 + alphaHitThreshold: 0.5 +--- !u!1 &2663532141933448284 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4210266305818195301} + - component: {fileID: 7084174367121215159} + - component: {fileID: 8358247987306301573} + - component: {fileID: 6264073236045925559} + m_Layer: 5 + m_Name: Ball 1 (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4210266305818195301 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2663532141933448284} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 2.1323996, y: 2.1323996, z: 2.1323996} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7007843749351456914} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -3.5, y: 230.6} + m_SizeDelta: {x: 137, y: 172} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7084174367121215159 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2663532141933448284} + m_CullTransparentMesh: 1 +--- !u!114 &8358247987306301573 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2663532141933448284} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 1412510325, guid: 6d69a607d0df04148bf50bc6ef2d6fcc, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &6264073236045925559 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2663532141933448284} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7667901d8aea645d28b5125a2ed546ce, type: 3} + m_Name: + m_EditorClassIdentifier: Features.Coloring::Darkmatter.Features.Coloring.UI.ColorRegionView + k__BackingField: Ball_1__1 + alphaHitThreshold: 0.5 +--- !u!1 &4186490129534872750 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1742841937534081069} + - component: {fileID: 7747220707014727277} + - component: {fileID: 6407676600503113451} + - component: {fileID: 5667220506450607617} + m_Layer: 5 + m_Name: Ball 1 (3) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1742841937534081069 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4186490129534872750} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.6899254, y: 1.6899254, z: 1.6899254} + m_ConstrainProportionsScale: 1 + m_Children: [] + m_Father: {fileID: 7007843749351456914} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 132.1, y: 128.1} + m_SizeDelta: {x: 206, y: 160} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7747220707014727277 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4186490129534872750} + m_CullTransparentMesh: 1 +--- !u!114 &6407676600503113451 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4186490129534872750} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 571736697, guid: 6d69a607d0df04148bf50bc6ef2d6fcc, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &5667220506450607617 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4186490129534872750} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7667901d8aea645d28b5125a2ed546ce, type: 3} + m_Name: + m_EditorClassIdentifier: Features.Coloring::Darkmatter.Features.Coloring.UI.ColorRegionView + k__BackingField: Ball_1__3 + alphaHitThreshold: 0.5 +--- !u!1 &5614629943100357722 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3374156459420035152} + - component: {fileID: 2903961533720080030} + - component: {fileID: 4568126265006522806} + - component: {fileID: 6761780684725240527} + m_Layer: 5 + m_Name: Ball 1 (5) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3374156459420035152 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5614629943100357722} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 2.1748946, y: 2.1748946, z: 2.1748946} + m_ConstrainProportionsScale: 1 + m_Children: [] + m_Father: {fileID: 7007843749351456914} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 9, y: -122} + m_SizeDelta: {x: 206, y: 160} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2903961533720080030 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5614629943100357722} + m_CullTransparentMesh: 1 +--- !u!114 &4568126265006522806 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5614629943100357722} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: -1754592932, guid: 6d69a607d0df04148bf50bc6ef2d6fcc, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &6761780684725240527 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5614629943100357722} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7667901d8aea645d28b5125a2ed546ce, type: 3} + m_Name: + m_EditorClassIdentifier: Features.Coloring::Darkmatter.Features.Coloring.UI.ColorRegionView + k__BackingField: Ball_1__5 + alphaHitThreshold: 0.5 --- !u!1 &5759944736263568396 GameObject: m_ObjectHideFlags: 0 @@ -65,9 +425,9 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 21300000, guid: c79f0374ffc23654fa0c341985d7e249, type: 3} + m_Sprite: {fileID: -1097588712, guid: 6d69a607d0df04148bf50bc6ef2d6fcc, type: 3} m_Type: 0 - m_PreserveAspect: 0 + m_PreserveAspect: 1 m_FillCenter: 1 m_FillMethod: 4 m_FillAmount: 1 @@ -101,10 +461,16 @@ RectTransform: m_GameObject: {fileID: 6799536857748686187} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 + m_LocalScale: {x: 2, y: 2, z: 2} + m_ConstrainProportionsScale: 1 m_Children: - {fileID: 5748400911909999140} + - {fileID: 4210266305818195301} + - {fileID: 6461212560377117779} + - {fileID: 1742841937534081069} + - {fileID: 4283726034190383322} + - {fileID: 3374156459420035152} + - {fileID: 1499171455522489850} - {fileID: 7953757931564007192} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -121,6 +487,186 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6799536857748686187} m_CullTransparentMesh: 1 +--- !u!1 &7016617008046089574 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6461212560377117779} + - component: {fileID: 6210273296947215134} + - component: {fileID: 8156181875320917282} + - component: {fileID: 7344593257758016015} + m_Layer: 5 + m_Name: Ball 1 (2) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6461212560377117779 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7016617008046089574} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.2475, y: 1.2475, z: 1.2475} + m_ConstrainProportionsScale: 1 + m_Children: [] + m_Father: {fileID: 7007843749351456914} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -82.1, y: 103.9} + m_SizeDelta: {x: 137, y: 172} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &6210273296947215134 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7016617008046089574} + m_CullTransparentMesh: 1 +--- !u!114 &8156181875320917282 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7016617008046089574} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 110110860, guid: 6d69a607d0df04148bf50bc6ef2d6fcc, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &7344593257758016015 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7016617008046089574} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7667901d8aea645d28b5125a2ed546ce, type: 3} + m_Name: + m_EditorClassIdentifier: Features.Coloring::Darkmatter.Features.Coloring.UI.ColorRegionView + k__BackingField: Ball_1__2 + alphaHitThreshold: 0.5 +--- !u!1 &8884255625160799694 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1499171455522489850} + - component: {fileID: 5584541620831607999} + - component: {fileID: 8261083789739009355} + - component: {fileID: 4960287606903619533} + m_Layer: 5 + m_Name: Ball 1 (6) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1499171455522489850 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8884255625160799694} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 2.2325292, y: 2.2325292, z: 2.2325292} + m_ConstrainProportionsScale: 1 + m_Children: [] + m_Father: {fileID: 7007843749351456914} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -203, y: -78} + m_SizeDelta: {x: 206, y: 160} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5584541620831607999 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8884255625160799694} + m_CullTransparentMesh: 1 +--- !u!114 &8261083789739009355 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8884255625160799694} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: -1699664395, guid: 6d69a607d0df04148bf50bc6ef2d6fcc, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &4960287606903619533 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8884255625160799694} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7667901d8aea645d28b5125a2ed546ce, type: 3} + m_Name: + m_EditorClassIdentifier: Features.Coloring::Darkmatter.Features.Coloring.UI.ColorRegionView + k__BackingField: Ball_1__6 + alphaHitThreshold: 0.5 --- !u!1 &9174428872297290907 GameObject: m_ObjectHideFlags: 0 @@ -134,7 +680,7 @@ GameObject: - component: {fileID: 5858260579706649738} - component: {fileID: 5165066291469502868} m_Layer: 5 - m_Name: Ball + m_Name: Ball 1 m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -149,15 +695,15 @@ RectTransform: m_GameObject: {fileID: 9174428872297290907} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalScale: {x: 1.6829311, y: 1.6829311, z: 1.6829311} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7007843749351456914} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 655, y: 655} + m_AnchoredPosition: {x: -179, y: 157} + m_SizeDelta: {x: 137, y: 172} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &2532004084275676791 CanvasRenderer: @@ -187,9 +733,9 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 21300000, guid: b83767bdc55064240a89bbaf542508ef, type: 3} + m_Sprite: {fileID: 809345179, guid: 6d69a607d0df04148bf50bc6ef2d6fcc, type: 3} m_Type: 0 - m_PreserveAspect: 0 + m_PreserveAspect: 1 m_FillCenter: 1 m_FillMethod: 4 m_FillAmount: 1 @@ -209,5 +755,5 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 7667901d8aea645d28b5125a2ed546ce, type: 3} m_Name: m_EditorClassIdentifier: Features.Coloring::Darkmatter.Features.Coloring.UI.ColorRegionView - k__BackingField: Ball + k__BackingField: Ball_1 alphaHitThreshold: 0.5 diff --git a/Assets/Darkmatter/Data/Drawings/Templates/Ball.asset b/Assets/Darkmatter/Data/Drawings/Templates/Ball.asset index 1e5ea2d..b79137d 100644 --- a/Assets/Darkmatter/Data/Drawings/Templates/Ball.asset +++ b/Assets/Darkmatter/Data/Drawings/Templates/Ball.asset @@ -14,13 +14,25 @@ MonoBehaviour: m_EditorClassIdentifier: Core::Darkmatter.Core.Data.Static.Features.DrawingTemplate.DrawingTemplateSO id: Ball displayName: Ball - defaultThumbnail: {fileID: 21300000, guid: c79f0374ffc23654fa0c341985d7e249, type: 3} + defaultThumbnail: {fileID: -1097588712, guid: 6d69a607d0df04148bf50bc6ef2d6fcc, type: 3} drawingPrefab: {fileID: 3523649744351506124, guid: ed2c3db5a20de9643a04dca1c61ff246, type: 3} coloringPrefab: {fileID: 6799536857748686187, guid: e02814fe96e1cf84491b9545b5642307, type: 3} completionAnimationPrefab: {fileID: 6152354576180930737, guid: 4ae77336fb29049ef91d839f601fca8a, type: 3} pieces: - {fileID: 11400000, guid: a3dc108a48b1e4f2196e8d49ae8e3edd, type: 2} regions: - - RegionId: Ball + - RegionId: Ball_1 + InitialColor: {r: 1, g: 1, b: 1, a: 1} + - RegionId: Ball_1__1 + InitialColor: {r: 1, g: 1, b: 1, a: 1} + - RegionId: Ball_1__2 + InitialColor: {r: 1, g: 1, b: 1, a: 1} + - RegionId: Ball_1__3 + InitialColor: {r: 1, g: 1, b: 1, a: 1} + - RegionId: Ball_1__4 + InitialColor: {r: 1, g: 1, b: 1, a: 1} + - RegionId: Ball_1__5 + InitialColor: {r: 1, g: 1, b: 1, a: 1} + - RegionId: Ball_1__6 InitialColor: {r: 1, g: 1, b: 1, a: 1} colorPaletteId: defaultPalette