This commit is contained in:
Savya Bikram Shah
2026-05-29 16:17:55 +05:45
parent 6c14eaaacf
commit 44bdb3286c
12 changed files with 401 additions and 60 deletions

View File

@@ -31,8 +31,10 @@ public class ColoringController : IColoringController, IDisposable
private GameObject _colorInstance;
private GameObject _colorButtonPrefab;
private GameObject _completionAnimationPrefab;
private readonly List<ColorRegionView> _regions = new();
private readonly List<ColorButton> _buttons = new();
private readonly Dictionary<string, Color> _authoredColors = new();
public ColoringController(
ColoringStateRepository repository,
@@ -63,6 +65,7 @@ public class ColoringController : IColoringController, IDisposable
ct.ThrowIfCancellationRequested();
CreateColorButtonInstances();
InitializeColorRegions(template, savedColors);
_bus.Publish(new RegionsInitializedSignal());
}
public void PaintRegion(string regionId, Color color)
@@ -86,15 +89,44 @@ public class ColoringController : IColoringController, IDisposable
public async UniTask PlayCompletionAnimationAsync(CancellationToken ct)
{
if (_colorInstance == null) return;
var animator = _colorInstance.GetComponentInChildren<Animator>(includeInactive: true);
if (animator == null || animator.runtimeAnimatorController == null) return;
if (_completionAnimationPrefab == null) return;
var instance = UnityEngine.Object.Instantiate(_completionAnimationPrefab, _refs.PaperRoot);
try
{
var view = instance.GetComponentInChildren<CompletionAnimationView>();
if (view == null) return;
await view.PlayAsync(ct);
}
finally
{
if (instance != null) UnityEngine.Object.Destroy(instance);
}
}
animator.Play(0, 0, 0f);
animator.Update(0f);
var length = animator.GetCurrentAnimatorStateInfo(0).length;
if (length <= 0f) return;
await UniTask.Delay(TimeSpan.FromSeconds(length), cancellationToken: ct);
public bool HasNonAuthoredColors
{
get
{
foreach (var region in _regions)
{
if (region == null) continue;
if (_authoredColors.TryGetValue(region.RegionId, out var authored) && region.Color != authored)
return true;
}
return false;
}
}
public void ResetAll()
{
if (_regions.Count == 0) return;
foreach (var region in _regions)
{
if (region == null) continue;
if (_authoredColors.TryGetValue(region.RegionId, out var authored))
region.SetColor(authored);
}
_history.Drop();
}
public void Clear()
@@ -107,6 +139,8 @@ public class ColoringController : IColoringController, IDisposable
_buttons.Clear();
_regions.Clear();
_authoredColors.Clear();
_completionAnimationPrefab = null;
if (_colorInstance != null)
{
@@ -120,12 +154,14 @@ public class ColoringController : IColoringController, IDisposable
private void InitializeColorRegions(IDrawingTemplate template, IReadOnlyDictionary<string, Color> savedColors)
{
_colorInstance = UnityEngine.Object.Instantiate(template.ColoringPrefab, _refs.PaperRoot);
_completionAnimationPrefab = template.CompletionAnimationPrefab;
var views = _colorInstance.GetComponentsInChildren<ColorRegionView>(includeInactive: true);
foreach (var region in views)
{
var id = region.RegionId;
var authoredColor = region.Color;
_authoredColors[id] = authoredColor;
var resumeColor = savedColors != null && savedColors.TryGetValue(id, out var saved)
? saved
: authoredColor;

View File

@@ -0,0 +1,30 @@
using System.Threading;
using Cysharp.Threading.Tasks;
using PrimeTween;
using UnityEngine;
namespace Darkmatter.Features.Coloring.UI
{
public class CompletionAnimationView : MonoBehaviour
{
[SerializeField] private RectTransform target;
[SerializeField] private float duration = 0.6f;
[SerializeField] private Vector3 startScale = Vector3.zero;
[SerializeField] private Vector3 endScale = Vector3.one;
[SerializeField] private Ease ease = Ease.OutBack;
public async UniTask PlayAsync(CancellationToken ct)
{
var rt = target != null ? target : transform as RectTransform;
if (rt == null) return;
rt.localScale = startScale;
await Tween.Scale(rt, endScale, duration, ease).ToUniTask(cancellationToken: ct);
}
private void OnDestroy()
{
var rt = target != null ? target : transform as RectTransform;
if (rt != null) Tween.StopAll(onTarget: rt);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 01fc8d24088db42b3a76d40120f81a9c

View File

@@ -212,6 +212,7 @@ namespace Darkmatter.Features.DrawingTemplates.Editor
EditorGUILayout.LabelField("Prefabs", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(so.FindProperty("drawingPrefab"), new GUIContent("Drawing Prefab (SlotMarkers)"));
EditorGUILayout.PropertyField(so.FindProperty("coloringPrefab"), new GUIContent("Coloring Prefab (ColorRegionViews)"));
EditorGUILayout.PropertyField(so.FindProperty("completionAnimationPrefab"), new GUIContent("Completion Animation Prefab"));
EditorGUILayout.Space(6);
EditorGUILayout.LabelField("Palette", EditorStyles.boldLabel);
@@ -231,7 +232,7 @@ namespace Darkmatter.Features.DrawingTemplates.Editor
Undo.RecordObject(t, "Clear Pieces");
var emptyPieces = new List<ShapeSO>();
t.EditorSet(t.Id, t.DisplayName, t.DefaultThumbnail, t.DrawingPrefab, t.ColoringPrefab,
emptyPieces, t.AuthoredRegions.ToList(), t.ColorPaletteId);
t.CompletionAnimationPrefab, emptyPieces, t.AuthoredRegions.ToList(), t.ColorPaletteId);
EditorUtility.SetDirty(t);
so.Update();
}
@@ -263,7 +264,7 @@ namespace Darkmatter.Features.DrawingTemplates.Editor
{
Undo.RecordObject(t, "Clear Regions");
t.EditorSet(t.Id, t.DisplayName, t.DefaultThumbnail, t.DrawingPrefab, t.ColoringPrefab,
t.Pieces.ToList(), new List<RegionAuthoring>(), t.ColorPaletteId);
t.CompletionAnimationPrefab, t.Pieces.ToList(), new List<RegionAuthoring>(), t.ColorPaletteId);
EditorUtility.SetDirty(t);
so.Update();
}
@@ -331,7 +332,7 @@ namespace Darkmatter.Features.DrawingTemplates.Editor
}
Undo.RecordObject(t, "Scan Drawing Prefab");
t.EditorSet(t.Id, t.DisplayName, t.DefaultThumbnail, t.DrawingPrefab, t.ColoringPrefab,
pieces, t.AuthoredRegions.ToList(), t.ColorPaletteId);
t.CompletionAnimationPrefab, pieces, t.AuthoredRegions.ToList(), t.ColorPaletteId);
EditorUtility.SetDirty(t);
_lastScanReport = $"Found {markers.Length} SlotMarker(s), {pieces.Count} unique ShapeSO. {missing} marker(s) had no ShapeSO assigned.";
Validate();
@@ -411,7 +412,7 @@ namespace Darkmatter.Features.DrawingTemplates.Editor
Undo.RecordObject(t, "Scan Coloring Prefab");
t.EditorSet(t.Id, t.DisplayName, t.DefaultThumbnail, t.DrawingPrefab, t.ColoringPrefab,
t.Pieces.ToList(), regions, t.ColorPaletteId);
t.CompletionAnimationPrefab, t.Pieces.ToList(), regions, t.ColorPaletteId);
EditorUtility.SetDirty(t);
var report = new System.Text.StringBuilder();
@@ -611,7 +612,7 @@ namespace Darkmatter.Features.DrawingTemplates.Editor
if (string.IsNullOrEmpty(path)) return;
var t = CreateInstance<DrawingTemplateSO>();
var name = Path.GetFileNameWithoutExtension(path);
t.EditorSet(name, name, null, null, null, new List<ShapeSO>(), new List<RegionAuthoring>(), "defaultPalette");
t.EditorSet(name, name, null, null, null, null, new List<ShapeSO>(), new List<RegionAuthoring>(), "defaultPalette");
AssetDatabase.CreateAsset(t, path);
AssetDatabase.SaveAssets();
Refresh();

View File

@@ -4,7 +4,8 @@
"references": [
"GUID:6a0a834eb41764f12ba55c3fb04a40cb",
"GUID:b0214a6008ed146ff8f122a6a9c2f6cc",
"GUID:c1c03c0e5b2f4412b9f2be1c20d6a9b1"
"GUID:c1c03c0e5b2f4412b9f2be1c20d6a9b1",
"GUID:b4c9f7fbf1e144933a1797dc208ece5f"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -1,5 +1,8 @@
using System;
using Darkmatter.Core.Contracts.Features.Coloring;
using Darkmatter.Core.Contracts.Features.History;
using Darkmatter.Core.Data.Signals.Features.Coloring;
using Darkmatter.Libs.Observer;
using VContainer.Unity;
namespace Darkmatter.Features.History
@@ -8,11 +11,18 @@ namespace Darkmatter.Features.History
{
private readonly HistoryButtonsView _view;
private readonly IUndoStack _undoStack;
private readonly IColoringController _coloring;
private readonly IEventBus _bus;
private IDisposable _initSub;
private IDisposable _colorAppliedSub;
public HistoryButtonsPresenter(IUndoStack undoStack, HistoryButtonsView view)
public HistoryButtonsPresenter(IUndoStack undoStack, HistoryButtonsView view, IColoringController coloring,
IEventBus bus)
{
_undoStack = undoStack;
_view = view;
_coloring = coloring;
_bus = bus;
}
public void Start()
@@ -22,11 +32,14 @@ namespace Darkmatter.Features.History
_view.OnClearClicked += HandleClearClicked;
UpdateButtonUI();
_undoStack.OnStackChanged += UpdateButtonUI;
_initSub = _bus.Subscribe<RegionsInitializedSignal>(_ => UpdateButtonUI());
_colorAppliedSub = _bus.Subscribe<ColorAppliedSignal>(_ => UpdateButtonUI());
}
private void HandleClearClicked()
{
_undoStack.Clear();
_coloring.ResetAll();
}
private void HandleRedoClicked()
@@ -43,7 +56,7 @@ namespace Darkmatter.Features.History
{
_view.SetUndoInteractable(_undoStack.CanUndo);
_view.SetRedoInteractable(_undoStack.CanRedo);
_view.SetClearInteractable(_undoStack.CanUndo);
_view.SetClearInteractable(_undoStack.CanUndo || _coloring.HasNonAuthoredColors);
}
public void Dispose()
@@ -52,6 +65,8 @@ namespace Darkmatter.Features.History
_view.OnRedoClicked -= HandleRedoClicked;
_view.OnClearClicked -= HandleClearClicked;
_undoStack.OnStackChanged -= UpdateButtonUI;
_initSub?.Dispose();
_colorAppliedSub?.Dispose();
}
}
}