stash work
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using AppleHills.Core.Settings;
|
||||
using Minigames.CardSorting.Data;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Core.Settings
|
||||
@@ -29,21 +28,21 @@ namespace Core.Settings
|
||||
[SerializeField] private AnimationCurve speedCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
|
||||
|
||||
[Header("Item Pools")]
|
||||
[Tooltip("Garbage items that can spawn (banana peels, cans, receipts, etc.)")]
|
||||
[SerializeField] private GarbageItemDefinition[] garbageItems = new GarbageItemDefinition[0];
|
||||
[Tooltip("Normal rarity card prefabs that can spawn")]
|
||||
[SerializeField] private GameObject[] normalCardPrefabs = new GameObject[0];
|
||||
|
||||
[Tooltip("Rare rarity card prefabs that can spawn")]
|
||||
[SerializeField] private GameObject[] rareCardPrefabs = new GameObject[0];
|
||||
|
||||
[Tooltip("Legendary rarity card prefabs that can spawn")]
|
||||
[SerializeField] private GameObject[] legendaryCardPrefabs = new GameObject[0];
|
||||
|
||||
[Tooltip("Garbage prefabs that can spawn")]
|
||||
[SerializeField] private GameObject[] garbagePrefabs = new GameObject[0];
|
||||
|
||||
[Header("Spawn Weights")]
|
||||
[Tooltip("Weight for spawning normal rarity cards")]
|
||||
[Range(0, 100)] [SerializeField] private float normalCardWeight = 40f;
|
||||
|
||||
[Tooltip("Weight for spawning rare rarity cards")]
|
||||
[Range(0, 100)] [SerializeField] private float rareCardWeight = 30f;
|
||||
|
||||
[Tooltip("Weight for spawning legendary rarity cards")]
|
||||
[Range(0, 100)] [SerializeField] private float legendCardWeight = 20f;
|
||||
|
||||
[Tooltip("Weight for spawning garbage items")]
|
||||
[Range(0, 100)] [SerializeField] private float garbageWeight = 10f;
|
||||
[Tooltip("Ratio of cards to garbage (0 = all garbage, 0.5 = 50/50 split, 1 = all cards)")]
|
||||
[Range(0, 1)] [SerializeField] private float cardToGarbageRatio = 0.5f;
|
||||
|
||||
[Header("Scoring")]
|
||||
[Tooltip("Points awarded for correct sort")]
|
||||
@@ -81,11 +80,11 @@ namespace Core.Settings
|
||||
public float InitialBeltSpeed => initialBeltSpeed;
|
||||
public float MaxBeltSpeed => maxBeltSpeed;
|
||||
public AnimationCurve SpeedCurve => speedCurve;
|
||||
public GarbageItemDefinition[] GarbageItems => garbageItems;
|
||||
public float NormalCardWeight => normalCardWeight;
|
||||
public float RareCardWeight => rareCardWeight;
|
||||
public float LegendCardWeight => legendCardWeight;
|
||||
public float GarbageWeight => garbageWeight;
|
||||
public GameObject[] NormalCardPrefabs => normalCardPrefabs;
|
||||
public GameObject[] RareCardPrefabs => rareCardPrefabs;
|
||||
public GameObject[] LegendaryCardPrefabs => legendaryCardPrefabs;
|
||||
public GameObject[] GarbagePrefabs => garbagePrefabs;
|
||||
public float CardToGarbageRatio => cardToGarbageRatio;
|
||||
public int CorrectSortPoints => correctSortPoints;
|
||||
public int IncorrectSortPenalty => incorrectSortPenalty;
|
||||
public int MissedItemPenalty => missedItemPenalty;
|
||||
|
||||
@@ -18,14 +18,14 @@ namespace Core.Settings
|
||||
float MaxBeltSpeed { get; }
|
||||
AnimationCurve SpeedCurve { get; }
|
||||
|
||||
// Item Pools
|
||||
GarbageItemDefinition[] GarbageItems { get; }
|
||||
// Item Pools - Arrays of prefabs
|
||||
GameObject[] NormalCardPrefabs { get; }
|
||||
GameObject[] RareCardPrefabs { get; }
|
||||
GameObject[] LegendaryCardPrefabs { get; }
|
||||
GameObject[] GarbagePrefabs { get; }
|
||||
|
||||
// Spawn Weights
|
||||
float NormalCardWeight { get; }
|
||||
float RareCardWeight { get; }
|
||||
float LegendCardWeight { get; }
|
||||
float GarbageWeight { get; }
|
||||
// Spawn Ratio (0 = all garbage, 1 = all cards)
|
||||
float CardToGarbageRatio { get; }
|
||||
|
||||
// Scoring
|
||||
int CorrectSortPoints { get; }
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using AppleHills.Data.CardSystem;
|
||||
using Core.Settings;
|
||||
using Data.CardSystem;
|
||||
using Minigames.CardSorting.Core;
|
||||
using Minigames.CardSorting.Data;
|
||||
using System.Collections.Generic;
|
||||
using UI.DragAndDrop.Core;
|
||||
using UnityEngine;
|
||||
@@ -20,8 +18,6 @@ namespace Minigames.CardSorting.Controllers
|
||||
private readonly Transform spawnPoint;
|
||||
private readonly Transform endPoint; // Visual end - scoring happens here
|
||||
private readonly Transform despawnPoint; // Off-screen - destruction happens here
|
||||
private readonly GameObject cardPrefab;
|
||||
private readonly GameObject garbagePrefab;
|
||||
private readonly ICardSortingSettings settings;
|
||||
private readonly Transform spawnContainer; // Container for all spawned items
|
||||
|
||||
@@ -30,7 +26,7 @@ namespace Minigames.CardSorting.Controllers
|
||||
private float currentSpeed;
|
||||
private SortableItem lastSpawnedItem; // Track last spawned item for distance-based spawning
|
||||
private float cachedSpawnOffsetX; // Cached random offset for next spawn
|
||||
private bool isGameOver = false; // Flag to stop conveyor when game ends
|
||||
private bool isGameOver; // Flag to stop conveyor when game ends
|
||||
|
||||
// Events - conveyor owns item lifecycle
|
||||
public event System.Action<SortableItem> OnItemSpawned; // Fired when new item spawns
|
||||
@@ -47,16 +43,12 @@ namespace Minigames.CardSorting.Controllers
|
||||
Transform spawnPoint,
|
||||
Transform endPoint,
|
||||
Transform despawnPoint,
|
||||
GameObject cardPrefab,
|
||||
GameObject garbagePrefab,
|
||||
ICardSortingSettings settings,
|
||||
Transform spawnContainer)
|
||||
{
|
||||
this.spawnPoint = spawnPoint;
|
||||
this.endPoint = endPoint;
|
||||
this.despawnPoint = despawnPoint;
|
||||
this.cardPrefab = cardPrefab;
|
||||
this.garbagePrefab = garbagePrefab;
|
||||
this.settings = settings;
|
||||
this.spawnContainer = spawnContainer;
|
||||
|
||||
@@ -114,33 +106,60 @@ namespace Minigames.CardSorting.Controllers
|
||||
|
||||
/// <summary>
|
||||
/// Spawn a new item at the spawn point.
|
||||
/// Uses cardToGarbageRatio (0-1) to determine card vs garbage spawn chance.
|
||||
/// If cards spawn, rarity is determined by array lengths.
|
||||
/// </summary>
|
||||
private SortableItem SpawnNewItem(float gameProgress)
|
||||
private void SpawnNewItem(float gameProgress)
|
||||
{
|
||||
// Weighted random: card or garbage?
|
||||
float totalWeight = settings.NormalCardWeight + settings.RareCardWeight +
|
||||
settings.LegendCardWeight + settings.GarbageWeight;
|
||||
|
||||
if (totalWeight <= 0f)
|
||||
{
|
||||
Debug.LogWarning("[ConveyorBeltController] Total spawn weight is 0, cannot spawn items!");
|
||||
return null;
|
||||
}
|
||||
|
||||
float roll = Random.Range(0f, totalWeight);
|
||||
// Use ratio to decide: card or garbage?
|
||||
float cardChance = settings.CardToGarbageRatio; // 0 = all garbage, 1 = all cards
|
||||
float roll = Random.Range(0f, 1f);
|
||||
|
||||
SortableItem item;
|
||||
|
||||
if (roll < settings.GarbageWeight)
|
||||
if (roll < cardChance)
|
||||
{
|
||||
// Spawn garbage
|
||||
item = SpawnGarbageItem();
|
||||
// Spawn card - determine rarity based on array lengths
|
||||
int normalWeight = settings.NormalCardPrefabs?.Length ?? 0;
|
||||
int rareWeight = settings.RareCardPrefabs?.Length ?? 0;
|
||||
int legendWeight = settings.LegendaryCardPrefabs?.Length ?? 0;
|
||||
|
||||
int totalCardWeight = normalWeight + rareWeight + legendWeight;
|
||||
|
||||
if (totalCardWeight <= 0)
|
||||
{
|
||||
Debug.LogWarning("[ConveyorBeltController] No card prefabs configured, spawning garbage instead");
|
||||
item = SpawnRandomPrefabFromArray(settings.GarbagePrefabs, true, CardRarity.Normal);
|
||||
}
|
||||
else
|
||||
{
|
||||
float rarityRoll = Random.Range(0f, totalCardWeight);
|
||||
CardRarity rarity;
|
||||
GameObject[] targetArray;
|
||||
|
||||
if (rarityRoll < normalWeight)
|
||||
{
|
||||
rarity = CardRarity.Normal;
|
||||
targetArray = settings.NormalCardPrefabs;
|
||||
}
|
||||
else if (rarityRoll < normalWeight + rareWeight)
|
||||
{
|
||||
rarity = CardRarity.Rare;
|
||||
targetArray = settings.RareCardPrefabs;
|
||||
}
|
||||
else
|
||||
{
|
||||
rarity = CardRarity.Legendary;
|
||||
targetArray = settings.LegendaryCardPrefabs;
|
||||
}
|
||||
|
||||
item = SpawnRandomPrefabFromArray(targetArray, false, rarity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Spawn card - determine rarity, get random card from CardSystemManager
|
||||
CardRarity rarity = DetermineRarity(roll);
|
||||
item = SpawnCardItem(rarity);
|
||||
// Spawn garbage
|
||||
item = SpawnRandomPrefabFromArray(settings.GarbagePrefabs, true, CardRarity.Normal);
|
||||
}
|
||||
|
||||
if (item != null)
|
||||
@@ -154,114 +173,61 @@ namespace Minigames.CardSorting.Controllers
|
||||
// Emit spawn event
|
||||
OnItemSpawned?.Invoke(item);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private SortableItem SpawnGarbageItem()
|
||||
{
|
||||
if (settings.GarbageItems == null || settings.GarbageItems.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("[ConveyorBeltController] No garbage items configured!");
|
||||
return null;
|
||||
}
|
||||
|
||||
GarbageItemDefinition garbage = SelectRandomGarbage();
|
||||
|
||||
// Apply random Y offset to spawn position
|
||||
float randomOffsetY = Random.Range(settings.SpawnOffsetY.x, settings.SpawnOffsetY.y);
|
||||
Vector3 spawnPos = spawnPoint.position + new Vector3(0f, randomOffsetY, 0f);
|
||||
|
||||
GameObject obj = Object.Instantiate(garbagePrefab, spawnPos, Quaternion.identity, spawnContainer);
|
||||
SortableItem item = obj.GetComponent<SortableItem>();
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
item.SetupAsGarbage(garbage);
|
||||
|
||||
// Apply card size (garbage items use same size as cards)
|
||||
ApplyCardSize(item);
|
||||
|
||||
// Subscribe to item events
|
||||
item.OnItemDroppedInBox += HandleItemDroppedInBox;
|
||||
item.OnItemDroppedOnFloor += HandleItemDroppedOnFloor;
|
||||
item.OnItemReturnedToConveyor += HandleItemReturnedToConveyor;
|
||||
|
||||
// Subscribe to drag events to remove from tracking
|
||||
item.OnDragStarted += HandleItemDragStarted;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[ConveyorBeltController] Garbage prefab missing SortableItem component!");
|
||||
Object.Destroy(obj);
|
||||
return null;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private SortableItem SpawnCardItem(CardRarity rarity)
|
||||
{
|
||||
// Get a random card of the specified rarity
|
||||
CardData cardData = GetRandomCardDataByRarity(rarity);
|
||||
|
||||
if (cardData == null)
|
||||
{
|
||||
Debug.LogWarning($"[ConveyorBeltController] No card data found for rarity {rarity}");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Apply random Y offset to spawn position
|
||||
float randomOffsetY = Random.Range(settings.SpawnOffsetY.x, settings.SpawnOffsetY.y);
|
||||
Vector3 spawnPos = spawnPoint.position + new Vector3(0f, randomOffsetY, 0f);
|
||||
|
||||
GameObject obj = Object.Instantiate(cardPrefab, spawnPos, Quaternion.identity, spawnContainer);
|
||||
SortableItem item = obj.GetComponent<SortableItem>();
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
item.SetupAsCard(cardData);
|
||||
|
||||
// Apply card size
|
||||
ApplyCardSize(item);
|
||||
|
||||
// Subscribe to item events
|
||||
item.OnItemDroppedInBox += HandleItemDroppedInBox;
|
||||
item.OnItemDroppedOnFloor += HandleItemDroppedOnFloor;
|
||||
item.OnItemReturnedToConveyor += HandleItemReturnedToConveyor;
|
||||
|
||||
// Subscribe to drag events to remove from tracking
|
||||
item.OnDragStarted += HandleItemDragStarted;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[ConveyorBeltController] Card prefab missing SortableItem component!");
|
||||
Object.Destroy(obj);
|
||||
return null;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to get a random card of a specific rarity.
|
||||
/// Gets a CardDefinition from CardSystemManager and converts to CardData.
|
||||
/// Does NOT affect player's collection or open boosters.
|
||||
/// Spawn a random prefab from an array.
|
||||
/// Prefab is assumed to have SortableItem component and be visually pre-configured.
|
||||
/// </summary>
|
||||
private CardData GetRandomCardDataByRarity(CardRarity targetRarity)
|
||||
private SortableItem SpawnRandomPrefabFromArray(GameObject[] prefabArray, bool isGarbage, CardRarity rarity)
|
||||
{
|
||||
// Get random card definition from manager
|
||||
var definition = CardSystemManager.Instance.GetRandomCardDefinitionByRarity(targetRarity);
|
||||
|
||||
if (definition == null)
|
||||
if (prefabArray == null || prefabArray.Length == 0)
|
||||
{
|
||||
Debug.LogWarning($"[ConveyorBeltController] No card definition found for rarity {targetRarity}");
|
||||
Debug.LogWarning($"[ConveyorBeltController] No prefabs configured for {(isGarbage ? "garbage" : rarity.ToString())}!");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create CardData from definition using constructor
|
||||
// This properly links the definition and sets all properties
|
||||
return new CardData(definition);
|
||||
// Pick random prefab
|
||||
GameObject prefab = prefabArray[Random.Range(0, prefabArray.Length)];
|
||||
|
||||
if (prefab == null)
|
||||
{
|
||||
Debug.LogWarning($"[ConveyorBeltController] Null prefab in array for {(isGarbage ? "garbage" : rarity.ToString())}!");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Apply random Y offset to spawn position
|
||||
float randomOffsetY = Random.Range(settings.SpawnOffsetY.x, settings.SpawnOffsetY.y);
|
||||
Vector3 spawnPos = spawnPoint.position + new Vector3(0f, randomOffsetY, 0f);
|
||||
|
||||
// Instantiate prefab
|
||||
GameObject obj = Object.Instantiate(prefab, spawnPos, Quaternion.identity, spawnContainer);
|
||||
SortableItem item = obj.GetComponent<SortableItem>();
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
Debug.LogError($"[ConveyorBeltController] Prefab missing SortableItem component: {prefab.name}");
|
||||
Object.Destroy(obj);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Initialize item based on type (just sets flags and state machine)
|
||||
if (isGarbage)
|
||||
{
|
||||
item.SetupAsGarbage();
|
||||
}
|
||||
else
|
||||
{
|
||||
item.SetupAsCard(rarity);
|
||||
}
|
||||
|
||||
// Subscribe to item events
|
||||
item.OnItemDroppedInBox += HandleItemDroppedInBox;
|
||||
item.OnItemDroppedOnFloor += HandleItemDroppedOnFloor;
|
||||
item.OnItemReturnedToConveyor += HandleItemReturnedToConveyor;
|
||||
item.OnDragStarted += HandleItemDragStarted;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private void UpdateBeltSpeed(float gameProgress)
|
||||
@@ -391,7 +357,7 @@ namespace Minigames.CardSorting.Controllers
|
||||
if (!activeItems.Contains(item))
|
||||
{
|
||||
activeItems.Add(item);
|
||||
Debug.Log($"[ConveyorBeltController] Item returned to conveyor: {item.CardData?.Name ?? item.GarbageItem?.DisplayName}");
|
||||
Debug.Log($"[ConveyorBeltController] Item returned to conveyor: {(item.IsGarbage ? "Garbage" : $"{item.Rarity} Card")}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,42 +386,7 @@ namespace Minigames.CardSorting.Controllers
|
||||
// Emit event for scoring
|
||||
OnItemDroppedOnFloor?.Invoke(item);
|
||||
|
||||
Debug.Log($"[ConveyorBeltController] Item dropped on floor: {item.CardData?.Name ?? item.GarbageItem?.DisplayName}");
|
||||
}
|
||||
|
||||
private CardRarity DetermineRarity(float roll)
|
||||
{
|
||||
// Adjust roll to be relative to card weights only (subtract garbage weight)
|
||||
float adjusted = roll - settings.GarbageWeight;
|
||||
|
||||
if (adjusted < settings.NormalCardWeight)
|
||||
return CardRarity.Normal;
|
||||
|
||||
if (adjusted < settings.NormalCardWeight + settings.RareCardWeight)
|
||||
return CardRarity.Rare;
|
||||
|
||||
return CardRarity.Legendary;
|
||||
}
|
||||
|
||||
private GarbageItemDefinition SelectRandomGarbage()
|
||||
{
|
||||
return settings.GarbageItems[Random.Range(0, settings.GarbageItems.Length)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply configured card size to spawned item.
|
||||
/// </summary>
|
||||
private void ApplyCardSize(SortableItem item)
|
||||
{
|
||||
if (item == null || item.Context == null || item.Context.RootTransform == null)
|
||||
return;
|
||||
|
||||
// Get the RectTransform to resize (root object)
|
||||
var rectTransform = item.Context.RootTransform.GetComponent<RectTransform>();
|
||||
if (rectTransform != null)
|
||||
{
|
||||
rectTransform.sizeDelta = settings.CardSize;
|
||||
}
|
||||
Debug.Log($"[ConveyorBeltController] Item dropped on floor: {(item.IsGarbage ? "Garbage" : $"{item.Rarity} Card")}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -477,7 +408,7 @@ namespace Minigames.CardSorting.Controllers
|
||||
|
||||
if (wasTracked)
|
||||
{
|
||||
Debug.Log($"[ConveyorBeltController] Item removed from tracking (picked up): {item.CardData?.Name ?? item.GarbageItem?.DisplayName}");
|
||||
Debug.Log($"[ConveyorBeltController] Item removed from tracking (picked up): {(item.IsGarbage ? "Garbage" : $"{item.Rarity} Card")}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Minigames.CardSorting.Core
|
||||
{
|
||||
if (item == null) return;
|
||||
|
||||
Debug.Log($"[ConveyorBeltSlot] Item dropped back on conveyor: {item.CardData?.Name ?? item.GarbageItem?.DisplayName}");
|
||||
Debug.Log($"[ConveyorBeltSlot] Item dropped back on conveyor: {(item.IsGarbage ? "Garbage" : $"{item.Rarity} Card")}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Minigames.CardSorting.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple sprite renderer for garbage items.
|
||||
/// Parallel to CardDisplay for cards.
|
||||
/// </summary>
|
||||
public class GarbageVisual : MonoBehaviour
|
||||
{
|
||||
[Header("Visual Components")]
|
||||
[SerializeField] private Image spriteRenderer;
|
||||
|
||||
/// <summary>
|
||||
/// Update the displayed sprite.
|
||||
/// </summary>
|
||||
public void UpdateDisplay(Sprite sprite)
|
||||
{
|
||||
if (spriteRenderer != null)
|
||||
{
|
||||
spriteRenderer.sprite = sprite;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Auto-find Image component if not assigned
|
||||
if (spriteRenderer == null)
|
||||
{
|
||||
spriteRenderer = GetComponent<Image>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b707770fc3a6448ea0dcd1b2fbf41e00
|
||||
timeCreated: 1763461824
|
||||
@@ -1,4 +1,4 @@
|
||||
using AppleHills.Data.CardSystem;
|
||||
using AppleHills.Data.CardSystem;
|
||||
using Core;
|
||||
using Core.SaveLoad;
|
||||
using Minigames.CardSorting.Data;
|
||||
@@ -21,10 +21,9 @@ namespace Minigames.CardSorting.Core
|
||||
[Header("Configuration")]
|
||||
[SerializeField] private string initialState = "OnConveyorState";
|
||||
|
||||
// Data tracking
|
||||
private bool isGarbage;
|
||||
private CardData cardData;
|
||||
private GarbageItemDefinition garbageItem;
|
||||
// Data tracking - set during spawn, no complex data initialization
|
||||
private bool _isGarbage;
|
||||
private CardRarity _rarity; // Only relevant for cards
|
||||
|
||||
// Events - item emits notifications, conveyor subscribes
|
||||
public event System.Action<SortableItem, SortingBox, bool> OnItemDroppedInBox;
|
||||
@@ -34,9 +33,8 @@ namespace Minigames.CardSorting.Core
|
||||
// Public accessors
|
||||
public SortableItemContext Context => context;
|
||||
public AppleMachine StateMachine => stateMachine;
|
||||
public bool IsGarbage => isGarbage;
|
||||
public CardData CardData => cardData;
|
||||
public GarbageItemDefinition GarbageItem => garbageItem;
|
||||
public bool IsGarbage => _isGarbage;
|
||||
public CardRarity Rarity => _rarity;
|
||||
|
||||
/// <summary>
|
||||
/// Get the correct box type for this item.
|
||||
@@ -45,10 +43,10 @@ namespace Minigames.CardSorting.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
if (isGarbage)
|
||||
if (_isGarbage)
|
||||
return BoxType.Trash;
|
||||
|
||||
return cardData.Rarity switch
|
||||
return _rarity switch
|
||||
{
|
||||
CardRarity.Normal => BoxType.Normal,
|
||||
CardRarity.Rare => BoxType.Rare,
|
||||
@@ -71,18 +69,12 @@ namespace Minigames.CardSorting.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup item as a card.
|
||||
/// Setup item as a card. Prefab is already visually configured.
|
||||
/// </summary>
|
||||
public void SetupAsCard(CardData data)
|
||||
public void SetupAsCard(CardRarity rarity)
|
||||
{
|
||||
isGarbage = false;
|
||||
cardData = data;
|
||||
garbageItem = null;
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
context.SetupAsCard(data);
|
||||
}
|
||||
_isGarbage = false;
|
||||
_rarity = rarity;
|
||||
|
||||
if (stateMachine != null && !string.IsNullOrEmpty(initialState))
|
||||
{
|
||||
@@ -91,18 +83,12 @@ namespace Minigames.CardSorting.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup item as garbage.
|
||||
/// Setup item as garbage. Prefab is already visually configured.
|
||||
/// </summary>
|
||||
public void SetupAsGarbage(GarbageItemDefinition garbage)
|
||||
public void SetupAsGarbage()
|
||||
{
|
||||
isGarbage = true;
|
||||
cardData = default;
|
||||
garbageItem = garbage;
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
context.SetupAsGarbage(garbage.Sprite);
|
||||
}
|
||||
_isGarbage = true;
|
||||
_rarity = CardRarity.Normal; // Default, not used for garbage
|
||||
|
||||
if (stateMachine != null && !string.IsNullOrEmpty(initialState))
|
||||
{
|
||||
@@ -125,7 +111,7 @@ namespace Minigames.CardSorting.Core
|
||||
}
|
||||
|
||||
// Default behavior if state doesn't handle
|
||||
Logging.Debug($"[SortableItem] Drag started on {(isGarbage ? garbageItem.DisplayName : cardData.Name)}");
|
||||
Logging.Debug($"[SortableItem] Drag started on {(_isGarbage ? "Garbage" : $"{_rarity} Card")}");
|
||||
}
|
||||
|
||||
// TODO: Fixed when base slot/draggable reworked
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using AppleHills.Data.CardSystem;
|
||||
using Core.SaveLoad;
|
||||
using UI.CardSystem;
|
||||
using Core.SaveLoad;
|
||||
using Minigames.CardSorting.Data;
|
||||
using UI.CardSystem.StateMachine;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -9,13 +8,13 @@ namespace Minigames.CardSorting.Core
|
||||
/// <summary>
|
||||
/// Shared context for sortable item states.
|
||||
/// Provides access to common components and data that states need.
|
||||
/// Routes data to appropriate visual component (CardDisplay for cards, GarbageVisual for garbage).
|
||||
/// Prefabs handle their own visual setup - no runtime initialization needed.
|
||||
/// </summary>
|
||||
public class SortableItemContext : MonoBehaviour
|
||||
{
|
||||
[Header("Visual Components (one or the other)")]
|
||||
[SerializeField] private CardDisplay cardDisplay; // For cards
|
||||
[SerializeField] private GarbageVisual garbageVisual; // For garbage
|
||||
[Header("Effect Components")]
|
||||
[Tooltip("Top-level overlay image for visual effects (blink red, etc). Should be hidden by default.")]
|
||||
[SerializeField] private UnityEngine.UI.Image blinkOverlayImage;
|
||||
|
||||
[Header("Shared Components")]
|
||||
[SerializeField] private CardAnimator animator;
|
||||
@@ -24,8 +23,7 @@ namespace Minigames.CardSorting.Core
|
||||
private AppleMachine stateMachine;
|
||||
|
||||
// Public accessors
|
||||
public CardDisplay CardDisplay => cardDisplay;
|
||||
public GarbageVisual GarbageVisual => garbageVisual;
|
||||
public UnityEngine.UI.Image BlinkOverlayImage => blinkOverlayImage;
|
||||
public CardAnimator Animator => animator;
|
||||
public Transform VisualTransform => visualTransform;
|
||||
public AppleMachine StateMachine => stateMachine;
|
||||
@@ -64,76 +62,16 @@ namespace Minigames.CardSorting.Core
|
||||
}
|
||||
}
|
||||
|
||||
if (cardDisplay == null && visualTransform != null)
|
||||
{
|
||||
cardDisplay = visualTransform.GetComponentInChildren<CardDisplay>();
|
||||
}
|
||||
|
||||
if (garbageVisual == null && visualTransform != null)
|
||||
{
|
||||
garbageVisual = visualTransform.GetComponentInChildren<GarbageVisual>();
|
||||
}
|
||||
|
||||
stateMachine = GetComponentInChildren<AppleMachine>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup as card item - CardDisplay handles all rendering.
|
||||
/// </summary>
|
||||
public void SetupAsCard(CardData cardData)
|
||||
{
|
||||
// Capture original root transform for drag animations
|
||||
// This preserves the tiny world-space Canvas scale (e.g., 0.05)
|
||||
var currentScale = transform.localScale;
|
||||
if (currentScale.x < 0.01f && currentScale.y < 0.01f && currentScale.z < 0.01f)
|
||||
{
|
||||
OriginalScale = Vector3.one; // Fallback if scale is ~0
|
||||
}
|
||||
else
|
||||
{
|
||||
OriginalScale = currentScale;
|
||||
}
|
||||
OriginalPosition = transform.localPosition;
|
||||
OriginalRotation = transform.localRotation;
|
||||
|
||||
if (cardDisplay != null)
|
||||
// Hide blink overlay initially
|
||||
if (blinkOverlayImage != null)
|
||||
{
|
||||
cardDisplay.SetupCard(cardData);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"[SortableItemContext] CardDisplay not found on {name}");
|
||||
blinkOverlayImage.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup as garbage item - simple sprite display.
|
||||
/// </summary>
|
||||
public void SetupAsGarbage(Sprite sprite)
|
||||
{
|
||||
// Capture original root transform for drag animations
|
||||
// This preserves the tiny world-space Canvas scale (e.g., 0.05)
|
||||
var currentScale = transform.localScale;
|
||||
if (currentScale.x < 0.01f && currentScale.y < 0.01f && currentScale.z < 0.01f)
|
||||
{
|
||||
OriginalScale = Vector3.one; // Fallback if scale is ~0
|
||||
}
|
||||
else
|
||||
{
|
||||
OriginalScale = currentScale;
|
||||
}
|
||||
OriginalPosition = transform.localPosition;
|
||||
OriginalRotation = transform.localRotation;
|
||||
|
||||
if (garbageVisual != null)
|
||||
{
|
||||
garbageVisual.UpdateDisplay(sprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"[SortableItemContext] GarbageVisual not found on {name}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ebfb8d9e40f4532b3a3919ced988330
|
||||
timeCreated: 1766069349
|
||||
@@ -21,8 +21,6 @@ namespace Minigames.CardSorting.Core
|
||||
[SerializeField] private Transform conveyorSpawnPoint;
|
||||
[SerializeField] private Transform conveyorEndPoint; // Visual end - items scored as missed here
|
||||
[SerializeField] private Transform conveyorDespawnPoint; // Off-screen - items destroyed here
|
||||
[SerializeField] private GameObject sortableCardPrefab;
|
||||
[SerializeField] private GameObject sortableGarbagePrefab;
|
||||
[SerializeField] private SortingBox[] sortingBoxes;
|
||||
[SerializeField] private Transform spawnedItemsContainer; // Container for all spawned items (optional, will auto-create if null)
|
||||
|
||||
@@ -44,8 +42,6 @@ namespace Minigames.CardSorting.Core
|
||||
conveyorSpawnPoint,
|
||||
conveyorEndPoint,
|
||||
conveyorDespawnPoint,
|
||||
sortableCardPrefab,
|
||||
sortableGarbagePrefab,
|
||||
_settings,
|
||||
GetOrCreateSpawnContainer()
|
||||
);
|
||||
@@ -213,23 +209,24 @@ namespace Minigames.CardSorting.Core
|
||||
}
|
||||
|
||||
// Blink the item red (if it still exists)
|
||||
if (item != null && item.Context != null && item.Context.Animator != null)
|
||||
if (item != null && item.Context != null && item.Context.Animator != null && item.Context.BlinkOverlayImage != null)
|
||||
{
|
||||
UnityEngine.UI.Image imageToBlink = null;
|
||||
// Show overlay before blinking
|
||||
item.Context.BlinkOverlayImage.enabled = true;
|
||||
|
||||
if (item.Context.CardDisplay != null)
|
||||
{
|
||||
imageToBlink = item.Context.CardDisplay.GetComponent<UnityEngine.UI.Image>();
|
||||
}
|
||||
else if (item.Context.GarbageVisual != null)
|
||||
{
|
||||
imageToBlink = item.Context.GarbageVisual.GetComponent<UnityEngine.UI.Image>();
|
||||
}
|
||||
item.Context.Animator.BlinkRed(item.Context.BlinkOverlayImage, 0.15f);
|
||||
|
||||
if (imageToBlink != null)
|
||||
{
|
||||
item.Context.Animator.BlinkRed(imageToBlink, 0.15f);
|
||||
}
|
||||
// Hide overlay after blink duration (assuming blink duration + buffer)
|
||||
StartCoroutine(HideOverlayAfterDelay(item.Context.BlinkOverlayImage, 0.5f));
|
||||
}
|
||||
}
|
||||
|
||||
private System.Collections.IEnumerator HideOverlayAfterDelay(UnityEngine.UI.Image overlay, float delay)
|
||||
{
|
||||
yield return new WaitForSeconds(delay);
|
||||
if (overlay != null)
|
||||
{
|
||||
overlay.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,7 +307,7 @@ namespace Minigames.CardSorting.Core
|
||||
{
|
||||
if (item != null && item.gameObject != null)
|
||||
{
|
||||
Logging.Debug($"[SortingGameManager] Destroying orphaned item: {item.CardData?.Name ?? item.GarbageItem?.DisplayName}");
|
||||
Logging.Debug($"[SortingGameManager] Destroying orphaned item: {(item.IsGarbage ? "Garbage" : $"{item.Rarity} Card")}");
|
||||
Destroy(item.gameObject);
|
||||
}
|
||||
}
|
||||
@@ -364,7 +361,7 @@ namespace Minigames.CardSorting.Core
|
||||
// Forward to public event for UI/other systems
|
||||
OnItemSpawned?.Invoke(item);
|
||||
|
||||
Logging.Debug($"[SortingGameManager] Item spawned: {item.CardData?.Name ?? item.GarbageItem?.DisplayName}");
|
||||
Logging.Debug($"[SortingGameManager] Item spawned: {(item.IsGarbage ? "Garbage" : $"{item.Rarity} Card")}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -383,11 +380,11 @@ namespace Minigames.CardSorting.Core
|
||||
Score.RecordMissedItem();
|
||||
PlayWrongStateFeedback(item);
|
||||
LoseLife();
|
||||
Logging.Debug($"[SortingGameManager] Trash fell off belt! {item.GarbageItem?.DisplayName} - PENALTY");
|
||||
Logging.Debug($"[SortingGameManager] Trash fell off belt! Garbage - PENALTY");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Debug($"[SortingGameManager] Card fell off belt: {item.CardData?.Name} - no penalty");
|
||||
Logging.Debug($"[SortingGameManager] Card fell off belt: {item.Rarity} Card - no penalty");
|
||||
}
|
||||
|
||||
// Fire global fell off belt event for effects
|
||||
@@ -412,11 +409,11 @@ namespace Minigames.CardSorting.Core
|
||||
Score.RecordIncorrectSort();
|
||||
PlayWrongStateFeedback(item);
|
||||
LoseLife();
|
||||
Logging.Debug($"[SortingGameManager] Trash dropped on floor! {item.GarbageItem?.DisplayName} - PENALTY");
|
||||
Logging.Debug($"[SortingGameManager] Trash dropped on floor! Garbage - PENALTY");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Debug($"[SortingGameManager] Card dropped on floor: {item.CardData?.Name} - no penalty");
|
||||
Logging.Debug($"[SortingGameManager] Card dropped on floor: {item.Rarity} Card - no penalty");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,7 +423,8 @@ namespace Minigames.CardSorting.Core
|
||||
/// </summary>
|
||||
private void OnConveyorItemDespawned(SortableItem item)
|
||||
{
|
||||
Logging.Debug($"[SortingGameManager] Item despawned: {item.CardData?.Name ?? item.GarbageItem?.DisplayName}");
|
||||
Logging.Debug($"[SortingGameManager] Item despawned: {(item.IsGarbage ? "Garbage" : $"{item.Rarity} Card")}");
|
||||
|
||||
|
||||
// Destroy the item
|
||||
if (item != null)
|
||||
@@ -446,7 +444,7 @@ namespace Minigames.CardSorting.Core
|
||||
if (correct)
|
||||
{
|
||||
Score.RecordCorrectSort();
|
||||
Logging.Debug($"[SortingGameManager] Correct sort! {item.CardData?.Name ?? item.GarbageItem?.DisplayName}");
|
||||
Logging.Debug($"[SortingGameManager] Correct sort! {(item.IsGarbage ? "Garbage" : $"{item.Rarity} Card")}");
|
||||
|
||||
// Fire global correct sort event for effects
|
||||
OnItemSortedCorrectly?.Invoke(item);
|
||||
@@ -460,14 +458,14 @@ namespace Minigames.CardSorting.Core
|
||||
Score.RecordIncorrectSort();
|
||||
PlayWrongStateFeedback(item);
|
||||
LoseLife();
|
||||
Logging.Debug($"[SortingGameManager] Incorrect trash sort! {item.GarbageItem?.DisplayName} - PENALTY");
|
||||
Logging.Debug($"[SortingGameManager] Incorrect trash sort! Garbage - PENALTY");
|
||||
|
||||
// Fire global incorrect sort event for effects
|
||||
OnItemSortedIncorrectly?.Invoke(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Debug($"[SortingGameManager] Card sorted incorrectly: {item.CardData?.Name} - no penalty");
|
||||
Logging.Debug($"[SortingGameManager] Card sorted incorrectly: {item.Rarity} Card - no penalty");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d88deb3df9e54bdb83b9a7ed1c7e3e27
|
||||
timeCreated: 1766069228
|
||||
@@ -1,38 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Minigames.CardSorting.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Definition for garbage items (banana peels, cans, receipts, etc.).
|
||||
/// Cards use existing CardDefinition from CardSystemManager.
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "GarbageItem", menuName = "Minigames/CardSorting/GarbageItem", order = 0)]
|
||||
public class GarbageItemDefinition : ScriptableObject
|
||||
{
|
||||
[Tooltip("Unique identifier for this garbage item")]
|
||||
[SerializeField] private string itemId;
|
||||
|
||||
[Tooltip("Display name for debugging")]
|
||||
[SerializeField] private string displayName;
|
||||
|
||||
[Tooltip("Sprite to display for this garbage item")]
|
||||
[SerializeField] private Sprite sprite;
|
||||
|
||||
// Public accessors
|
||||
public string ItemId => itemId;
|
||||
public string DisplayName => displayName;
|
||||
public Sprite Sprite => sprite;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnValidate()
|
||||
{
|
||||
// Auto-generate itemId from asset name if empty
|
||||
if (string.IsNullOrEmpty(itemId))
|
||||
{
|
||||
itemId = name;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e69a2167710437798b1980126d5a4f6
|
||||
timeCreated: 1763461765
|
||||
@@ -57,28 +57,12 @@ namespace Minigames.CardSorting.StateMachine.States
|
||||
|
||||
private void StartBlinkingRed()
|
||||
{
|
||||
if (_context.Animator == null) return;
|
||||
if (_context.Animator == null || _context.BlinkOverlayImage == null) return;
|
||||
|
||||
// Get the image to tint (CardDisplay or GarbageVisual)
|
||||
UnityEngine.UI.Image imageToBlink = null;
|
||||
// Show overlay before blinking
|
||||
_context.BlinkOverlayImage.enabled = true;
|
||||
|
||||
if (_context.CardDisplay != null)
|
||||
{
|
||||
imageToBlink =
|
||||
_context.CardDisplay.GetComponent<UnityEngine.UI.Image>()
|
||||
?? _context.CardDisplay.GetComponentInChildren<UnityEngine.UI.Image>();
|
||||
}
|
||||
else if (_context.GarbageVisual != null)
|
||||
{
|
||||
imageToBlink =
|
||||
_context.GarbageVisual.GetComponent<UnityEngine.UI.Image>()
|
||||
?? _context.GarbageVisual.GetComponentInChildren<UnityEngine.UI.Image>();
|
||||
}
|
||||
|
||||
if (imageToBlink != null)
|
||||
{
|
||||
_context.Animator.BlinkRed(imageToBlink);
|
||||
}
|
||||
_context.Animator.BlinkRed(_context.BlinkOverlayImage);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
|
||||
Reference in New Issue
Block a user