Refactor, cleanup code and add documentaiton
This commit is contained in:
211
Assets/Scripts/CardSystem/Core/Card.cs
Normal file
211
Assets/Scripts/CardSystem/Core/Card.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using AppleHills.Data.CardSystem;
|
||||
using Core;
|
||||
using Core.SaveLoad;
|
||||
using UI.DragAndDrop.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI.CardSystem.StateMachine
|
||||
{
|
||||
// ...existing code...
|
||||
public class Card : DraggableObject
|
||||
{
|
||||
[Header("Components")]
|
||||
[SerializeField] private CardContext context;
|
||||
[SerializeField] private CardAnimator animator;
|
||||
[SerializeField] private AppleMachine stateMachine;
|
||||
|
||||
[Header("Configuration")]
|
||||
[SerializeField] private string initialState = "IdleState";
|
||||
|
||||
// Public accessors
|
||||
public CardContext Context => context;
|
||||
public CardAnimator Animator => animator;
|
||||
public AppleMachine StateMachine => stateMachine;
|
||||
public CardData CardData => context?.CardData;
|
||||
|
||||
// State inspection properties for booster flow
|
||||
public bool IsIdle => GetCurrentStateName() == CardStateNames.Idle;
|
||||
public bool IsRevealing => !IsIdle && !IsComplete;
|
||||
public bool IsComplete => context?.BoosterContext.HasCompletedReveal ?? false;
|
||||
|
||||
// Event fired when this card is successfully placed into an AlbumCardSlot
|
||||
public event System.Action<Card, AlbumCardSlot> OnPlacedInAlbumSlot;
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize(); // Call DraggableObject initialization
|
||||
|
||||
// Auto-find components if not assigned
|
||||
if (context == null)
|
||||
context = GetComponent<CardContext>();
|
||||
|
||||
if (animator == null)
|
||||
animator = GetComponent<CardAnimator>();
|
||||
|
||||
if (stateMachine == null)
|
||||
stateMachine = GetComponentInChildren<AppleMachine>();
|
||||
}
|
||||
|
||||
#region DraggableObject Hooks - Trigger State Transitions
|
||||
|
||||
protected override void OnDragStartedHook()
|
||||
{
|
||||
base.OnDragStartedHook();
|
||||
|
||||
// Always emit the generic drag started event for external consumers (AlbumViewPage, etc.)
|
||||
context?.NotifyDragStarted();
|
||||
|
||||
// Check if current state wants to handle drag behavior
|
||||
if (stateMachine?.currentState != null)
|
||||
{
|
||||
var dragHandler = stateMachine.currentState.GetComponent<ICardStateDragHandler>();
|
||||
if (dragHandler != null && dragHandler.OnCardDragStarted(context))
|
||||
{
|
||||
return; // State handled it, don't do default behavior
|
||||
}
|
||||
}
|
||||
|
||||
// Default behavior: transition to DraggingState
|
||||
// Logging.Debug($"[Card] Drag started on {CardData?.Name}, transitioning to DraggingState");
|
||||
// ChangeState("DraggingState");
|
||||
}
|
||||
|
||||
protected override void OnDragEndedHook()
|
||||
{
|
||||
base.OnDragEndedHook();
|
||||
|
||||
// Always emit the generic drag ended event for external consumers
|
||||
context?.NotifyDragEnded();
|
||||
|
||||
// Check if current state wants to handle drag end
|
||||
if (stateMachine?.currentState != null)
|
||||
{
|
||||
var dragHandler = stateMachine.currentState.GetComponent<ICardStateDragHandler>();
|
||||
if (dragHandler != null && dragHandler.OnCardDragEnded(context))
|
||||
{
|
||||
return; // State handled it
|
||||
}
|
||||
}
|
||||
|
||||
// Default behavior for states that don't implement custom drag end
|
||||
string current = GetCurrentStateName();
|
||||
if (current == CardStateNames.Dragging)
|
||||
{
|
||||
if (CurrentSlot is AlbumCardSlot albumSlot)
|
||||
{
|
||||
Logging.Debug($"[Card] Dropped in album slot, transitioning to PlacedInSlotState");
|
||||
var placedState = GetStateComponent<States.CardPlacedInSlotState>(CardStateNames.PlacedInSlot);
|
||||
if (placedState != null)
|
||||
{
|
||||
placedState.SetParentSlot(albumSlot);
|
||||
}
|
||||
ChangeState(CardStateNames.PlacedInSlot);
|
||||
OnPlacedInAlbumSlot?.Invoke(this, albumSlot);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Debug("[Card] Dropped outside valid slot, returning to RevealedState");
|
||||
ChangeState(CardStateNames.Revealed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Setup the card with data and optional initial state
|
||||
/// </summary>
|
||||
public void SetupCard(CardData data, string startState = null)
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
context.SetupCard(data);
|
||||
}
|
||||
|
||||
// Start the state machine with specified or default state
|
||||
string targetState = startState ?? initialState;
|
||||
if (stateMachine != null && !string.IsNullOrEmpty(targetState))
|
||||
{
|
||||
stateMachine.ChangeState(targetState);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup for booster reveal flow (starts at IdleState, will flip on click)
|
||||
/// Dragging is DISABLED for booster cards
|
||||
/// States will query CardSystemManager for collection state as needed
|
||||
/// </summary>
|
||||
public void SetupForBoosterReveal(CardData data, bool isNew)
|
||||
{
|
||||
SetupCard(data, CardStateNames.Idle);
|
||||
SetDraggingEnabled(false); // Booster cards cannot be dragged
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup for album placement (starts at PlacedInSlotState)
|
||||
/// Dragging is DISABLED once placed in slot
|
||||
/// </summary>
|
||||
public void SetupForAlbumSlot(CardData data, AlbumCardSlot slot)
|
||||
{
|
||||
SetupCard(data, CardStateNames.PlacedInSlot);
|
||||
SetDraggingEnabled(false); // Cards in slots cannot be dragged out
|
||||
|
||||
// Set the parent slot on the PlacedInSlotState
|
||||
var placedState = GetStateComponent<States.CardPlacedInSlotState>(CardStateNames.PlacedInSlot);
|
||||
if (placedState != null)
|
||||
{
|
||||
placedState.SetParentSlot(slot);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup for album pending state (starts at PendingFaceDownState)
|
||||
/// Dragging is ENABLED; state will assign data when dragged
|
||||
/// </summary>
|
||||
public void SetupForAlbumPending()
|
||||
{
|
||||
// Start with no data; state will assign when dragged
|
||||
SetupCard(null, CardStateNames.PendingFaceDown);
|
||||
SetDraggingEnabled(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transition to a specific state
|
||||
/// </summary>
|
||||
public void ChangeState(string stateName)
|
||||
{
|
||||
if (stateMachine != null)
|
||||
{
|
||||
stateMachine.ChangeState(stateName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a specific state component by name
|
||||
/// </summary>
|
||||
public T GetStateComponent<T>(string stateName) where T : AppleState
|
||||
{
|
||||
if (stateMachine == null) return null;
|
||||
|
||||
Transform stateTransform = stateMachine.transform.Find(stateName);
|
||||
if (stateTransform != null)
|
||||
{
|
||||
return stateTransform.GetComponent<T>();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current active state name
|
||||
/// </summary>
|
||||
public string GetCurrentStateName()
|
||||
{
|
||||
if (stateMachine?.currentState != null)
|
||||
{
|
||||
return stateMachine.currentState.name;
|
||||
}
|
||||
return "None";
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/CardSystem/Core/Card.cs.meta
Normal file
3
Assets/Scripts/CardSystem/Core/Card.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d97dd4e4bc3246e9bed5ac227f13de10
|
||||
timeCreated: 1762884900
|
||||
23
Assets/Scripts/CardSystem/Core/CardBack.cs
Normal file
23
Assets/Scripts/CardSystem/Core/CardBack.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UI.CardSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple component representing card back visuals; toggle visibility.
|
||||
/// </summary>
|
||||
public class CardBack : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Image backImage;
|
||||
|
||||
public void Show()
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/CardSystem/Core/CardBack.cs.meta
Normal file
3
Assets/Scripts/CardSystem/Core/CardBack.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37d815ba7b02481786cc1953678a3e8e
|
||||
timeCreated: 1763322207
|
||||
188
Assets/Scripts/CardSystem/Core/CardContext.cs
Normal file
188
Assets/Scripts/CardSystem/Core/CardContext.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using AppleHills.Data.CardSystem;
|
||||
using Core.SaveLoad;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI.CardSystem.StateMachine
|
||||
{
|
||||
/// <summary>
|
||||
/// Shared context for card states.
|
||||
/// Provides access to common components and data that states need.
|
||||
/// </summary>
|
||||
public class CardContext : MonoBehaviour
|
||||
{
|
||||
[Header("Core Components")]
|
||||
[SerializeField] private CardDisplay cardDisplay;
|
||||
[SerializeField] private CardAnimator cardAnimator;
|
||||
private AppleMachine stateMachine;
|
||||
|
||||
[Header("Card Data")]
|
||||
private CardData cardData;
|
||||
|
||||
// Injected dependencies
|
||||
private AlbumViewPage albumViewPage;
|
||||
|
||||
// Public accessors
|
||||
public CardDisplay CardDisplay => cardDisplay;
|
||||
public CardAnimator Animator => cardAnimator;
|
||||
public AppleMachine StateMachine => stateMachine;
|
||||
public Transform RootTransform => transform;
|
||||
public CardData CardData => cardData;
|
||||
|
||||
/// <summary>
|
||||
/// Get the injected AlbumViewPage (null if not set)
|
||||
/// </summary>
|
||||
public AlbumViewPage AlbumViewPage => albumViewPage;
|
||||
|
||||
// Runtime state
|
||||
public bool IsClickable { get; set; } = true;
|
||||
|
||||
// Original transform data (captured on spawn for shrink animations)
|
||||
public Vector3 OriginalScale { get; private set; }
|
||||
public Vector3 OriginalPosition { get; private set; }
|
||||
public Quaternion OriginalRotation { get; private set; }
|
||||
|
||||
// Generic drag event - fired when drag starts, consumers decide how to handle based on current state
|
||||
public event Action<CardContext> OnDragStarted;
|
||||
|
||||
// Generic drag end event - fired when drag ends, consumers decide how to handle based on current state
|
||||
public event Action<CardContext> OnDragEnded;
|
||||
|
||||
// Booster-specific context (optional, only set for booster flow cards)
|
||||
private BoosterCardContext boosterContext;
|
||||
public BoosterCardContext BoosterContext
|
||||
{
|
||||
get
|
||||
{
|
||||
if (boosterContext == null)
|
||||
boosterContext = new BoosterCardContext();
|
||||
return boosterContext;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inject AlbumViewPage dependency
|
||||
/// </summary>
|
||||
public void SetAlbumViewPage(AlbumViewPage page)
|
||||
{
|
||||
albumViewPage = page;
|
||||
}
|
||||
|
||||
// Helper method for states/card to signal drag started
|
||||
public void NotifyDragStarted()
|
||||
{
|
||||
OnDragStarted?.Invoke(this);
|
||||
}
|
||||
|
||||
// Helper method for states/card to signal drag ended
|
||||
public void NotifyDragEnded()
|
||||
{
|
||||
OnDragEnded?.Invoke(this);
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Auto-find components if not assigned
|
||||
if (cardDisplay == null)
|
||||
cardDisplay = GetComponentInChildren<CardDisplay>();
|
||||
|
||||
if (cardAnimator == null)
|
||||
cardAnimator = GetComponent<CardAnimator>();
|
||||
|
||||
if (stateMachine == null)
|
||||
stateMachine = GetComponentInChildren<AppleMachine>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Subscribe to CardDisplay click and route to active state
|
||||
if (cardDisplay != null)
|
||||
{
|
||||
cardDisplay.OnCardClicked += HandleCardDisplayClicked;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (cardDisplay != null)
|
||||
{
|
||||
cardDisplay.OnCardClicked -= HandleCardDisplayClicked;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleCardDisplayClicked(CardDisplay _)
|
||||
{
|
||||
// Gate by clickability
|
||||
if (!IsClickable) return;
|
||||
if (stateMachine == null || stateMachine.currentState == null) return;
|
||||
|
||||
var handler = stateMachine.currentState.GetComponent<ICardClickHandler>();
|
||||
if (handler != null)
|
||||
{
|
||||
handler.OnCardClicked(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup the card with data
|
||||
/// </summary>
|
||||
public void SetupCard(CardData data)
|
||||
{
|
||||
cardData = data;
|
||||
|
||||
// Reset booster context if it exists
|
||||
if (boosterContext != null)
|
||||
{
|
||||
boosterContext.Reset();
|
||||
}
|
||||
|
||||
// Capture original transform for shrink animations.
|
||||
// If current scale is ~0 (pop-in staging), default to Vector3.one.
|
||||
var currentScale = transform.localScale;
|
||||
if (currentScale.x < 0.01f && currentScale.y < 0.01f && currentScale.z < 0.01f)
|
||||
{
|
||||
OriginalScale = Vector3.one;
|
||||
}
|
||||
else
|
||||
{
|
||||
OriginalScale = currentScale;
|
||||
}
|
||||
OriginalPosition = transform.localPosition;
|
||||
OriginalRotation = transform.localRotation;
|
||||
|
||||
if (cardDisplay != null)
|
||||
{
|
||||
cardDisplay.SetupCard(data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update card data without re-capturing original transform values.
|
||||
/// Use this when assigning data to an already-initialized card (e.g., pending cards on drag).
|
||||
/// This prevents changing OriginalScale when the card is already correctly sized.
|
||||
/// </summary>
|
||||
public void UpdateCardData(CardData data)
|
||||
{
|
||||
cardData = data;
|
||||
|
||||
// Reset booster context if it exists
|
||||
if (boosterContext != null)
|
||||
{
|
||||
boosterContext.Reset();
|
||||
}
|
||||
|
||||
// Don't re-capture OriginalScale/Position/Rotation
|
||||
// This preserves the transform values captured during initial setup
|
||||
|
||||
if (cardDisplay != null)
|
||||
{
|
||||
cardDisplay.SetupCard(data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the card display component
|
||||
/// </summary>
|
||||
public CardDisplay GetCardDisplay() => cardDisplay;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/CardSystem/Core/CardContext.cs.meta
Normal file
3
Assets/Scripts/CardSystem/Core/CardContext.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b3126aaaa66448fa3d5bd772aaf5784
|
||||
timeCreated: 1762884650
|
||||
311
Assets/Scripts/CardSystem/Core/CardDisplay.cs
Normal file
311
Assets/Scripts/CardSystem/Core/CardDisplay.cs
Normal file
@@ -0,0 +1,311 @@
|
||||
using System;
|
||||
using AppleHills.Data.CardSystem;
|
||||
using Core;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace UI.CardSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays a single card using the new visual system with frames, overlays, backgrounds, and zone shapes.
|
||||
/// </summary>
|
||||
public class CardDisplay : MonoBehaviour, IPointerClickHandler
|
||||
{
|
||||
[Header("UI Elements")]
|
||||
[SerializeField] private TextMeshProUGUI cardNameText;
|
||||
[SerializeField] private Image cardImage;
|
||||
[SerializeField] private Image frameImage;
|
||||
[SerializeField] private Image overlayImage;
|
||||
[SerializeField] private Image backgroundImage;
|
||||
[SerializeField] private Image zoneShapeImage;
|
||||
|
||||
[Header("Card Data")]
|
||||
[SerializeField] private CardData cardData;
|
||||
|
||||
[Header("Visual Settings")]
|
||||
[SerializeField] private CardVisualConfig visualConfig;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[Header("Editor Tools")]
|
||||
[SerializeField] private CardDefinition editorCardDefinition;
|
||||
#endif
|
||||
|
||||
// Events
|
||||
public event Action<CardDisplay> OnCardClicked;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the card display with the given card data
|
||||
/// </summary>
|
||||
public void SetupCard(CardData data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
Logging.Warning("[CardDisplay] Attempted to setup card with null data");
|
||||
return;
|
||||
}
|
||||
|
||||
cardData = data;
|
||||
UpdateCardVisuals();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates all visual elements based on current card data
|
||||
/// </summary>
|
||||
private void UpdateCardVisuals()
|
||||
{
|
||||
if (cardData == null)
|
||||
{
|
||||
ClearCard();
|
||||
return;
|
||||
}
|
||||
|
||||
if (visualConfig == null)
|
||||
{
|
||||
Logging.Warning("[CardDisplay] No CardVisualConfig assigned. Visuals may not display correctly.");
|
||||
}
|
||||
|
||||
// Update text
|
||||
UpdateCardName();
|
||||
|
||||
// Update main card image
|
||||
UpdateCardImage();
|
||||
|
||||
// Update rarity-based visuals (frame and overlay)
|
||||
UpdateRarityVisuals();
|
||||
|
||||
// Update zone-based visuals (background and shape)
|
||||
UpdateZoneVisuals();
|
||||
|
||||
Logging.Debug($"[CardDisplay] Updated visuals for card: {cardData.Name} (Rarity: {cardData.Rarity}, Zone: {cardData.Zone})");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Updates the card name text
|
||||
/// </summary>
|
||||
private void UpdateCardName()
|
||||
{
|
||||
if (cardNameText != null)
|
||||
{
|
||||
cardNameText.text = cardData.Name ?? "Unknown Card";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the main card image
|
||||
/// </summary>
|
||||
private void UpdateCardImage()
|
||||
{
|
||||
if (cardImage != null)
|
||||
{
|
||||
if (cardData.CardImage != null)
|
||||
{
|
||||
cardImage.sprite = cardData.CardImage;
|
||||
cardImage.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
cardImage.sprite = null;
|
||||
cardImage.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates frame and overlay based on card rarity
|
||||
/// </summary>
|
||||
private void UpdateRarityVisuals()
|
||||
{
|
||||
if (visualConfig == null) return;
|
||||
|
||||
// Update frame
|
||||
if (frameImage != null)
|
||||
{
|
||||
Sprite frameSprite = visualConfig.GetRarityFrame(cardData.Rarity);
|
||||
if (frameSprite != null)
|
||||
{
|
||||
frameImage.sprite = frameSprite;
|
||||
frameImage.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
frameImage.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Update overlay (can be null for some rarities)
|
||||
if (overlayImage != null)
|
||||
{
|
||||
Sprite overlaySprite = visualConfig.GetRarityOverlay(cardData.Rarity);
|
||||
if (overlaySprite != null)
|
||||
{
|
||||
overlayImage.sprite = overlaySprite;
|
||||
overlayImage.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayImage.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates background and zone shape based on card zone and rarity
|
||||
/// Special handling for Legendary cards
|
||||
/// </summary>
|
||||
private void UpdateZoneVisuals()
|
||||
{
|
||||
if (visualConfig == null) return;
|
||||
|
||||
// Update background
|
||||
// Legendary cards get special background, others get zone background
|
||||
if (backgroundImage != null)
|
||||
{
|
||||
Sprite bgSprite = visualConfig.GetBackground(cardData.Zone, cardData.Rarity);
|
||||
if (bgSprite != null)
|
||||
{
|
||||
backgroundImage.sprite = bgSprite;
|
||||
backgroundImage.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
backgroundImage.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Update zone shape
|
||||
// Legendary cards don't show shapes
|
||||
if (zoneShapeImage != null)
|
||||
{
|
||||
Sprite shapeSprite = visualConfig.GetZoneShape(cardData.Zone, cardData.Rarity);
|
||||
if (shapeSprite != null)
|
||||
{
|
||||
zoneShapeImage.sprite = shapeSprite;
|
||||
zoneShapeImage.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
zoneShapeImage.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all visual elements
|
||||
/// </summary>
|
||||
private void ClearCard()
|
||||
{
|
||||
if (cardNameText != null) cardNameText.text = "";
|
||||
if (cardImage != null) cardImage.enabled = false;
|
||||
if (frameImage != null) frameImage.enabled = false;
|
||||
if (overlayImage != null) overlayImage.enabled = false;
|
||||
if (backgroundImage != null) backgroundImage.enabled = false;
|
||||
if (zoneShapeImage != null) zoneShapeImage.enabled = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the card is clicked
|
||||
/// </summary>
|
||||
public void OnClick()
|
||||
{
|
||||
OnCardClicked?.Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the card data associated with this display
|
||||
/// </summary>
|
||||
public CardData GetCardData()
|
||||
{
|
||||
return cardData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the visual config reference
|
||||
/// </summary>
|
||||
public void SetVisualConfig(CardVisualConfig config)
|
||||
{
|
||||
visualConfig = config;
|
||||
if (cardData != null)
|
||||
{
|
||||
UpdateCardVisuals();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle pointer click - simply emit the click event
|
||||
/// </summary>
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
OnCardClicked?.Invoke(this);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Editor-only: Preview a card from the assigned definition
|
||||
/// </summary>
|
||||
public void PreviewFromDefinition()
|
||||
{
|
||||
if (editorCardDefinition == null)
|
||||
{
|
||||
Debug.LogWarning("[CardDisplay] No Card Definition assigned in Editor Tools.");
|
||||
return;
|
||||
}
|
||||
|
||||
CardData previewData = editorCardDefinition.CreateCardData();
|
||||
SetupCard(previewData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Editor-only: Clear the preview
|
||||
/// </summary>
|
||||
public void ClearPreview()
|
||||
{
|
||||
cardData = null;
|
||||
ClearCard();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(CardDisplay))]
|
||||
public class CardDisplayEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
DrawDefaultInspector();
|
||||
|
||||
CardDisplay display = (CardDisplay)target;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Editor Preview Tools", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Preview Card"))
|
||||
{
|
||||
display.PreviewFromDefinition();
|
||||
EditorUtility.SetDirty(display);
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Clear Preview"))
|
||||
{
|
||||
display.ClearPreview();
|
||||
EditorUtility.SetDirty(display);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.HelpBox(
|
||||
"Assign a Card Definition in 'Editor Tools' section, then click 'Preview Card' to see how it will look at runtime.",
|
||||
MessageType.Info
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
3
Assets/Scripts/CardSystem/Core/CardDisplay.cs.meta
Normal file
3
Assets/Scripts/CardSystem/Core/CardDisplay.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72cb26621865420aa763a66c06eb7f6d
|
||||
timeCreated: 1762380447
|
||||
Reference in New Issue
Block a user