Updates to card testing scene

This commit is contained in:
Michal Pikulski
2025-11-12 14:39:38 +01:00
committed by Michal Pikulski
parent 4e7f774386
commit 755082c67d
26 changed files with 1336 additions and 841 deletions

View File

@@ -1,252 +0,0 @@
using System;
using System.Collections;
using AppleHills.Data.CardSystem;
using Core;
using Data.CardSystem;
using Pixelplacement;
using UI.DragAndDrop.Core;
using UnityEngine;
namespace UI.CardSystem
{
/// <summary>
/// Draggable card for album reveal system.
/// Handles both tap and drag-hold interactions for revealing cards.
/// Auto-snaps to matching album slot on release/tap.
/// </summary>
public class AlbumCardPlacementDraggable : DraggableObject
{
[Header("Album Card Settings")]
[SerializeField] private FlippableCard flippableCard;
[SerializeField] private float holdRevealDelay = 0.1f;
private CardData _cardData;
private bool _isRevealed = false;
private bool _isDragRevealing = false;
private bool _waitingForPlacementTap = false;
private Coroutine _holdRevealCoroutine;
private bool _isHolding = false; // Track if pointer is currently down
// Events
public event Action<AlbumCardPlacementDraggable, CardData> OnCardRevealed;
public event Action<AlbumCardPlacementDraggable, CardData> OnCardPlacedInAlbum;
public CardData CardData => _cardData;
public bool IsRevealed => _isRevealed;
public CardZone Zone => _cardData?.Zone ?? CardZone.AppleHills;
protected override void Initialize()
{
base.Initialize();
// Auto-find FlippableCard if not assigned
if (flippableCard == null)
{
flippableCard = GetComponent<FlippableCard>();
}
}
/// <summary>
/// Setup the card data (stores it but doesn't reveal until tapped/dragged)
/// </summary>
public void SetupCard(CardData data)
{
_cardData = data;
if (flippableCard != null)
{
flippableCard.SetupCard(data);
}
}
/// <summary>
/// Reveal the card (flip to show front)
/// </summary>
public void RevealCard()
{
if (_isRevealed)
{
return;
}
_isRevealed = true;
if (flippableCard != null)
{
flippableCard.FlipToReveal();
}
OnCardRevealed?.Invoke(this, _cardData);
}
/// <summary>
/// Snap to the matching album slot
/// </summary>
public void SnapToAlbumSlot()
{
if (_cardData == null)
{
Logging.Warning("[AlbumCardPlacementDraggable] Cannot snap to slot - no card data assigned.");
return;
}
// Find all album card slots in the scene
AlbumCardSlot[] allSlots = FindObjectsByType<AlbumCardSlot>(FindObjectsSortMode.None);
AlbumCardSlot matchingSlot = null;
foreach (var slot in allSlots)
{
if (slot.CanAcceptCard(_cardData))
{
matchingSlot = slot;
break;
}
}
if (matchingSlot != null)
{
SetDraggingEnabled(false);
// NEW FLOW: Extract AlbumCard FIRST, then tween it
if (flippableCard != null)
{
AlbumCard extractedCard = flippableCard.ExtractAlbumCard(matchingSlot.transform);
if (extractedCard != null)
{
// Notify slot that card was placed
matchingSlot.OnCardPlaced(extractedCard);
// NOW tween the extracted AlbumCard into position
TweenExtractedCardToSlot(extractedCard, () =>
{
// After animation completes
Logging.Debug($"[AlbumCardPlacementDraggable] Card placement animation complete for {_cardData.Name}");
// Notify that card was placed
OnCardPlacedInAlbum?.Invoke(this, _cardData);
// Destroy this wrapper (the AlbumPlacementCard)
Destroy(gameObject);
});
}
else
{
Logging.Warning("[AlbumCardPlacementDraggable] Failed to extract AlbumCard from wrapper!");
}
}
}
else
{
Logging.Warning($"[AlbumCardPlacementDraggable] Could not find matching slot for card '{_cardData.Name}' (Zone: {_cardData.Zone}, Index: {_cardData.CollectionIndex})");
}
}
/// <summary>
/// Tween the extracted AlbumCard into its slot position
/// Tweens from current size to slot size - AspectRatioFitter handles width
/// </summary>
private void TweenExtractedCardToSlot(AlbumCard card, System.Action onComplete)
{
Transform cardTransform = card.transform;
RectTransform cardRect = cardTransform as RectTransform;
if (cardRect != null)
{
// Get target height from slot
RectTransform slotRect = cardTransform.parent as RectTransform;
float targetHeight = slotRect != null ? slotRect.rect.height : cardRect.sizeDelta.y;
// Tween from current size to target size (AspectRatioFitter will adjust width)
Vector2 targetSize = new Vector2(cardRect.sizeDelta.x, targetHeight);
Tween.Size(cardRect, targetSize, snapDuration, 0f, Tween.EaseOutBack);
// Tween position and rotation to slot center
Tween.LocalPosition(cardRect, Vector3.zero, snapDuration, 0f, Tween.EaseOutBack);
Tween.LocalRotation(cardTransform, Quaternion.identity, snapDuration, 0f, Tween.EaseOutBack,
completeCallback: () =>
{
Logging.Debug($"[AlbumCardPlacementDraggable] Tween complete for extracted card {card.name}, final height: {cardRect.sizeDelta.y}");
onComplete?.Invoke();
});
}
else
{
// No RectTransform, just reset and call callback
cardTransform.localPosition = Vector3.zero;
cardTransform.localRotation = Quaternion.identity;
onComplete?.Invoke();
}
}
protected override void OnPointerDownHook()
{
base.OnPointerDownHook();
_isHolding = true;
// Start hold-reveal timer if card not yet revealed
if (!_isRevealed && _holdRevealCoroutine == null)
{
_holdRevealCoroutine = StartCoroutine(HoldRevealTimer());
}
}
protected override void OnPointerUpHook(bool longPress)
{
base.OnPointerUpHook(longPress);
_isHolding = false;
// Cancel hold timer if running
if (_holdRevealCoroutine != null)
{
StopCoroutine(_holdRevealCoroutine);
_holdRevealCoroutine = null;
}
else
{
}
// Handle tap (not dragged)
if (!_wasDragged)
{
if (!_isRevealed)
{
// First tap: reveal the card
RevealCard();
_waitingForPlacementTap = true;
}
else if (_waitingForPlacementTap)
{
// Second tap: snap to slot
_waitingForPlacementTap = false;
SnapToAlbumSlot();
}
else
{
}
}
else if (_isDragRevealing)
{
// Was drag-revealed, auto-snap on release
_isDragRevealing = false;
SnapToAlbumSlot();
}
}
/// <summary>
/// Coroutine to reveal card after holding for specified duration
/// </summary>
private IEnumerator HoldRevealTimer()
{
yield return new WaitForSeconds(holdRevealDelay);
// If still holding after delay, reveal the card
if (!_isRevealed && _isHolding)
{
RevealCard();
_isDragRevealing = true;
}
_holdRevealCoroutine = null;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 706803638ea24880bae19c87d3851ce6
timeCreated: 1762470947

View File

@@ -1,62 +0,0 @@
using AppleHills.Data.CardSystem;
using UI.DragAndDrop.Core;
using UnityEngine;
namespace UI.CardSystem.DragDrop
{
/// <summary>
/// Card-specific implementation of DraggableObject.
/// Manages card data and card-specific drag behavior.
/// </summary>
public class CardDraggable : DraggableObject
{
[Header("Card Data")]
[SerializeField] private CardData cardData;
// Events
public event System.Action<CardDraggable, CardData> OnCardDataChanged;
public CardData CardData => cardData;
/// <summary>
/// Set the card data for this draggable card
/// </summary>
public void SetCardData(CardData data)
{
cardData = data;
OnCardDataChanged?.Invoke(this, cardData);
// Update visual if it exists
if (_visualInstance != null && _visualInstance is CardDraggableVisual cardVisual)
{
cardVisual.RefreshCardDisplay();
}
}
protected override void OnDragStartedHook()
{
base.OnDragStartedHook();
// Card-specific drag started behavior
}
protected override void OnDragEndedHook()
{
base.OnDragEndedHook();
// Card-specific drag ended behavior
}
protected override void OnSelectionChangedHook(bool selected)
{
base.OnSelectionChangedHook(selected);
// Card-specific selection behavior
}
protected override void OnSlotChangedHook(DraggableSlot previousSlot, DraggableSlot newSlot)
{
base.OnSlotChangedHook(previousSlot, newSlot);
// Card-specific slot changed behavior
// Could trigger events for card collection reordering, etc.
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 5a2741bb7299441b9f9bd44d746ebb4b
timeCreated: 1762420654

View File

@@ -1,121 +0,0 @@
using AppleHills.Data.CardSystem;
using UI.DragAndDrop.Core;
using UnityEngine;
namespace UI.CardSystem.DragDrop
{
/// <summary>
/// Visual representation for CardDraggable.
/// Uses the existing CardDisplay component to render the card.
/// </summary>
public class CardDraggableVisual : DraggableVisual
{
[Header("Card Visual Components")]
[SerializeField] private CardDisplay cardDisplay;
[SerializeField] private Transform shadowTransform;
[SerializeField] private float shadowOffset = 20f;
private Vector3 _shadowInitialPosition;
private CardDraggable _cardDraggable;
public CardDisplay CardDisplay => cardDisplay;
public override void Initialize(DraggableObject parent)
{
base.Initialize(parent);
_cardDraggable = parent as CardDraggable;
// Get CardDisplay component if not assigned
if (cardDisplay == null)
{
cardDisplay = GetComponentInChildren<CardDisplay>();
}
// Initialize shadow
if (shadowTransform != null)
{
_shadowInitialPosition = shadowTransform.localPosition;
}
// Subscribe to card data changes
if (_cardDraggable != null)
{
_cardDraggable.OnCardDataChanged += HandleCardDataChanged;
// Initial card setup
if (_cardDraggable.CardData != null && cardDisplay != null)
{
cardDisplay.SetupCard(_cardDraggable.CardData);
}
}
}
protected override void UpdateVisualContent()
{
// CardDisplay handles its own rendering, no need to update every frame
// This is called every frame but we only update when card data changes
}
/// <summary>
/// Refresh the card display with current data
/// </summary>
public void RefreshCardDisplay()
{
if (cardDisplay != null && _cardDraggable != null && _cardDraggable.CardData != null)
{
cardDisplay.SetupCard(_cardDraggable.CardData);
}
}
private void HandleCardDataChanged(CardDraggable draggable, CardData data)
{
RefreshCardDisplay();
}
protected override void OnPointerDownVisual()
{
base.OnPointerDownVisual();
// Move shadow down when pressed
if (shadowTransform != null)
{
shadowTransform.localPosition = _shadowInitialPosition + (-Vector3.up * shadowOffset);
}
}
protected override void OnPointerUpVisual(bool longPress)
{
base.OnPointerUpVisual(longPress);
// Restore shadow position
if (shadowTransform != null)
{
shadowTransform.localPosition = _shadowInitialPosition;
}
}
protected override void OnDragStartedVisual()
{
base.OnDragStartedVisual();
// Card-specific visual effects when dragging starts
}
protected override void OnDragEndedVisual()
{
base.OnDragEndedVisual();
// Card-specific visual effects when dragging ends
}
protected override void OnDestroy()
{
base.OnDestroy();
if (_cardDraggable != null)
{
_cardDraggable.OnCardDataChanged -= HandleCardDataChanged;
}
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 2a4c3884410d44f98182cd8119a972a4
timeCreated: 1762420668