fixes
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Darkmatter.Core.Contracts.Features.Capture;
|
||||
using Darkmatter.Core.Contracts.Features.Coloring;
|
||||
using Darkmatter.Core.Contracts.Features.DrawingCatalog;
|
||||
using Darkmatter.Core.Contracts.Features.GameplayFlow;
|
||||
using Darkmatter.Core.Contracts.Features.Progression;
|
||||
@@ -21,6 +22,7 @@ namespace Darkmatter.Features.Capture
|
||||
private readonly CaptureConfig _config;
|
||||
private readonly IProgressionSystem _progression;
|
||||
private readonly IDrawingTemplateCatalog _catalog;
|
||||
private readonly IColoringController _coloring;
|
||||
|
||||
public CaptureSystem(
|
||||
ICaptureService captureService,
|
||||
@@ -29,7 +31,8 @@ namespace Darkmatter.Features.Capture
|
||||
IEventBus bus,
|
||||
CaptureConfig config,
|
||||
IProgressionSystem progression,
|
||||
IDrawingTemplateCatalog catalog)
|
||||
IDrawingTemplateCatalog catalog,
|
||||
IColoringController coloring)
|
||||
{
|
||||
_captureService = captureService;
|
||||
_galleryService = galleryService;
|
||||
@@ -38,10 +41,16 @@ namespace Darkmatter.Features.Capture
|
||||
_config = config;
|
||||
_progression = progression;
|
||||
_catalog = catalog;
|
||||
_coloring = coloring;
|
||||
}
|
||||
|
||||
public async UniTask<byte[]> CapturePngAsync(bool saveToGallery = false, CancellationToken ct = default)
|
||||
{
|
||||
// The completion celebration hides the real drawing and shows an animation object
|
||||
// under PaperRoot. Capturing then would grab the animation, not the art, so skip.
|
||||
// A null result keeps the existing thumbnail and skips the gallery write (both no-op on null).
|
||||
if (_coloring.IsPlayingCompletionAnimation) return null;
|
||||
|
||||
var png = await _captureService.CapturePngAsync(_refs.PaperRoot.gameObject, _config.CaptureScale, ct);
|
||||
if (!saveToGallery || png == null || png.Length == 0) return png;
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ public class ColoringController : IColoringController, IDisposable
|
||||
private GameObject _colorButtonPrefab;
|
||||
private GameObject _completionAnimationInstance;
|
||||
private CompletionAnimationView _completionAnimationView;
|
||||
private bool _isPlayingCompletionAnimation;
|
||||
private readonly List<ColorRegionView> _regions = new();
|
||||
private readonly List<ColorButton> _buttons = new();
|
||||
private readonly Dictionary<string, Color> _authoredColors = new();
|
||||
@@ -88,17 +89,21 @@ public class ColoringController : IColoringController, IDisposable
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
public bool IsPlayingCompletionAnimation => _isPlayingCompletionAnimation;
|
||||
|
||||
public async UniTask PlayCompletionAnimationAsync(CancellationToken ct)
|
||||
{
|
||||
if (_completionAnimationInstance == null || _completionAnimationView == null) return;
|
||||
if (_colorInstance != null) _colorInstance.SetActive(false);
|
||||
_completionAnimationInstance.SetActive(true);
|
||||
_isPlayingCompletionAnimation = true;
|
||||
try
|
||||
{
|
||||
await _completionAnimationView.PlayAsync(ct);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isPlayingCompletionAnimation = false;
|
||||
if (_completionAnimationInstance != null)
|
||||
_completionAnimationInstance.SetActive(false);
|
||||
}
|
||||
@@ -133,6 +138,7 @@ public class ColoringController : IColoringController, IDisposable
|
||||
public void Clear()
|
||||
{
|
||||
_history.Drop();
|
||||
_isPlayingCompletionAnimation = false;
|
||||
|
||||
foreach (var button in _buttons)
|
||||
if (button != null)
|
||||
|
||||
@@ -136,6 +136,12 @@ namespace Darkmatter.Features.GameplayFlow.Systems
|
||||
|
||||
public async UniTask NextAsync(CancellationToken ct)
|
||||
{
|
||||
// Drop any debounced autosave so it can't fire during/after the completion
|
||||
// animation and capture the animation (or an empty paper) into the thumbnail.
|
||||
_autosaveCts?.Cancel();
|
||||
_autosaveCts?.Dispose();
|
||||
_autosaveCts = null;
|
||||
|
||||
await SaveCurrentAsync(ct);
|
||||
_refs.Confetti.Play();
|
||||
_sfx.Play(SfxId.FireWorkLaunch);
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
private Vector2 _origAnchorMax;
|
||||
private Vector2 _origPivot;
|
||||
private bool _origPreserveAspect;
|
||||
private Vector3 _homeScale = Vector3.one;
|
||||
|
||||
// Per-drag state
|
||||
private RectTransform _rt;
|
||||
@@ -45,6 +46,8 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
private Vector2 _trayPosInDragRoot;
|
||||
private Vector2 _dragSizeDelta;
|
||||
private Vector3 _dragLocalScale;
|
||||
private float _dragOrigAlpha;
|
||||
private Tween _dragScaleTween;
|
||||
private Sequence _previewSeq;
|
||||
private Sequence _snapSettle;
|
||||
private bool _locked;
|
||||
@@ -68,6 +71,14 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
if (image != null) image.color = color;
|
||||
}
|
||||
|
||||
private void SetAlpha(float a)
|
||||
{
|
||||
if (image == null) return;
|
||||
var c = image.color;
|
||||
c.a = a;
|
||||
image.color = c;
|
||||
}
|
||||
|
||||
public void Setup(
|
||||
ShapeSO shape,
|
||||
SlotMarker[] candidateSlots,
|
||||
@@ -95,6 +106,7 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
_origAnchorMax = RectTransform.anchorMax;
|
||||
_origPivot = RectTransform.pivot;
|
||||
_origPreserveAspect = image != null && image.preserveAspect;
|
||||
_homeScale = RectTransform.localScale;
|
||||
|
||||
image.sprite = shape.Sprite;
|
||||
ApplyTrayPose();
|
||||
@@ -104,6 +116,10 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
{
|
||||
if (_locked) return;
|
||||
|
||||
// Kill any tweens still running on this piece (e.g. a return/preview from a
|
||||
// re-grab mid-animation) so the new drag starts from a clean, known pose.
|
||||
Tween.StopAll(onTarget: RectTransform);
|
||||
|
||||
if (_dragRoot != null && RectTransform.parent != _dragRoot)
|
||||
{
|
||||
RectTransform.SetParent(_dragRoot, worldPositionStays: true);
|
||||
@@ -114,11 +130,20 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
_eventCam = e.pressEventCamera;
|
||||
_trayPosInDragRoot = RectTransform.anchoredPosition;
|
||||
_dragSizeDelta = RectTransform.sizeDelta;
|
||||
_dragLocalScale = RectTransform.localScale;
|
||||
// Use the canonical resting scale, not the live value, so a re-grab mid-tween
|
||||
// can't bake a drifted scale into the drag base.
|
||||
_dragLocalScale = _homeScale;
|
||||
RectTransform.localScale = _homeScale;
|
||||
_grabOffset = RectTransform.anchoredPosition - ScreenToLocal(e.position);
|
||||
_inPreview = false;
|
||||
|
||||
Tween.LocalScale(RectTransform, _dragLocalScale * _cfg.DragScale, _cfg.SnapDuration, Ease.OutQuad);
|
||||
if (image != null)
|
||||
{
|
||||
_dragOrigAlpha = image.color.a;
|
||||
SetAlpha(_cfg.DragAlpha);
|
||||
}
|
||||
|
||||
_dragScaleTween = Tween.Scale(RectTransform, _dragLocalScale * _cfg.DragScale, _cfg.SnapDuration, Ease.OutQuad);
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData e)
|
||||
@@ -156,6 +181,12 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
{
|
||||
if (_locked) return;
|
||||
|
||||
// Stop the begin-drag scale-up so it can't fight the return/snap pose.
|
||||
// Leave _previewSeq alive — the snap path lets it settle.
|
||||
if (_dragScaleTween.isAlive) _dragScaleTween.Stop();
|
||||
|
||||
SetAlpha(_dragOrigAlpha);
|
||||
|
||||
var target = FindSlotUnder(e.position);
|
||||
if (target != null)
|
||||
{
|
||||
@@ -184,6 +215,7 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
|
||||
private void AnimatePreviewPose(bool toSlot)
|
||||
{
|
||||
if (_dragScaleTween.isAlive) _dragScaleTween.Stop();
|
||||
if (_previewSeq.isAlive) _previewSeq.Stop();
|
||||
|
||||
if (toSlot && _activeSlot != null)
|
||||
@@ -361,6 +393,7 @@ namespace Darkmatter.Features.ShapeBuilder.UI
|
||||
{
|
||||
RectTransform.sizeDelta = _traySize;
|
||||
RectTransform.localRotation = Quaternion.identity;
|
||||
RectTransform.localScale = _homeScale;
|
||||
}
|
||||
|
||||
private Vector2 ScreenToLocal(Vector2 screenPos)
|
||||
|
||||
Reference in New Issue
Block a user