Fix card cleanup after dismissing minigame
This commit is contained in:
@@ -23,6 +23,7 @@ namespace Minigames.CardSorting.Controllers
|
||||
private readonly GameObject cardPrefab;
|
||||
private readonly GameObject garbagePrefab;
|
||||
private readonly ICardSortingSettings settings;
|
||||
private readonly Transform spawnContainer; // Container for all spawned items
|
||||
|
||||
private List<SortableItem> activeItems = new List<SortableItem>();
|
||||
private HashSet<SortableItem> missedItems = new HashSet<SortableItem>(); // Items past visual end, moving to despawn
|
||||
@@ -48,7 +49,8 @@ namespace Minigames.CardSorting.Controllers
|
||||
Transform despawnPoint,
|
||||
GameObject cardPrefab,
|
||||
GameObject garbagePrefab,
|
||||
ICardSortingSettings settings)
|
||||
ICardSortingSettings settings,
|
||||
Transform spawnContainer)
|
||||
{
|
||||
this.spawnPoint = spawnPoint;
|
||||
this.endPoint = endPoint;
|
||||
@@ -56,6 +58,7 @@ namespace Minigames.CardSorting.Controllers
|
||||
this.cardPrefab = cardPrefab;
|
||||
this.garbagePrefab = garbagePrefab;
|
||||
this.settings = settings;
|
||||
this.spawnContainer = spawnContainer;
|
||||
|
||||
this.currentSpeed = settings.InitialBeltSpeed;
|
||||
this.lastSpawnedItem = null; // No items spawned yet
|
||||
@@ -169,7 +172,7 @@ namespace Minigames.CardSorting.Controllers
|
||||
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);
|
||||
GameObject obj = Object.Instantiate(garbagePrefab, spawnPos, Quaternion.identity, spawnContainer);
|
||||
SortableItem item = obj.GetComponent<SortableItem>();
|
||||
|
||||
if (item != null)
|
||||
@@ -212,7 +215,7 @@ namespace Minigames.CardSorting.Controllers
|
||||
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);
|
||||
GameObject obj = Object.Instantiate(cardPrefab, spawnPos, Quaternion.identity, spawnContainer);
|
||||
SortableItem item = obj.GetComponent<SortableItem>();
|
||||
|
||||
if (item != null)
|
||||
@@ -497,6 +500,39 @@ namespace Minigames.CardSorting.Controllers
|
||||
|
||||
Debug.Log("[ConveyorBeltController] Conveyor stopped - all items disabled");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroy all active items on the conveyor.
|
||||
/// Called when quitting to main level to cleanup spawned items.
|
||||
/// </summary>
|
||||
public void DestroyAllItems()
|
||||
{
|
||||
Debug.Log($"[ConveyorBeltController] Destroying {activeItems.Count} active items");
|
||||
|
||||
// Unsubscribe from all item events and destroy them
|
||||
for (int i = activeItems.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var item = activeItems[i];
|
||||
if (item != null)
|
||||
{
|
||||
// Unsubscribe from events
|
||||
item.OnItemDroppedInBox -= HandleItemDroppedInBox;
|
||||
item.OnItemDroppedOnFloor -= HandleItemDroppedOnFloor;
|
||||
item.OnItemReturnedToConveyor -= HandleItemReturnedToConveyor;
|
||||
item.OnDragStarted -= HandleItemDragStarted;
|
||||
|
||||
// Destroy the game object
|
||||
Object.Destroy(item.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear all tracking
|
||||
activeItems.Clear();
|
||||
missedItems.Clear();
|
||||
lastSpawnedItem = null;
|
||||
|
||||
Debug.Log("[ConveyorBeltController] All items destroyed and tracking cleared");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Minigames.CardSorting.Core
|
||||
[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)
|
||||
|
||||
[Header("Effects")]
|
||||
[SerializeField] private CinemachineImpulseSource impulseSource; // Screen shake on incorrect sort
|
||||
@@ -45,7 +46,8 @@ namespace Minigames.CardSorting.Core
|
||||
conveyorDespawnPoint,
|
||||
sortableCardPrefab,
|
||||
sortableGarbagePrefab,
|
||||
_settings
|
||||
_settings,
|
||||
GetOrCreateSpawnContainer()
|
||||
);
|
||||
|
||||
// Public accessor for states to check game over status
|
||||
@@ -91,6 +93,26 @@ namespace Minigames.CardSorting.Core
|
||||
Logging.Debug("[SortingGameManager] Initialized with settings");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or create the container for spawned items.
|
||||
/// Ensures all cards/garbage are organized in the hierarchy.
|
||||
/// </summary>
|
||||
private Transform GetOrCreateSpawnContainer()
|
||||
{
|
||||
if (spawnedItemsContainer != null)
|
||||
return spawnedItemsContainer;
|
||||
|
||||
// Auto-create container if not assigned
|
||||
var containerObj = new GameObject("[Spawned Items]");
|
||||
spawnedItemsContainer = containerObj.transform;
|
||||
spawnedItemsContainer.SetParent(transform); // Parent to manager for organization
|
||||
spawnedItemsContainer.localPosition = Vector3.zero;
|
||||
|
||||
Logging.Debug("[SortingGameManager] Auto-created spawned items container");
|
||||
|
||||
return spawnedItemsContainer;
|
||||
}
|
||||
|
||||
internal override void OnManagedStart()
|
||||
{
|
||||
// Subscribe to score events
|
||||
@@ -247,6 +269,54 @@ namespace Minigames.CardSorting.Core
|
||||
StartCoroutine(EndGameSequence());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup all dynamically spawned items (cards/garbage).
|
||||
/// Called when quitting to main level to prevent items from lingering on screen.
|
||||
/// </summary>
|
||||
public void CleanupAllItems()
|
||||
{
|
||||
Logging.Debug("[SortingGameManager] Cleaning up all spawned items");
|
||||
|
||||
// Tell conveyor to destroy all active items
|
||||
// Use the property which handles lazy initialization
|
||||
Conveyor?.DestroyAllItems();
|
||||
|
||||
// Also destroy any remaining children in the spawn container
|
||||
if (spawnedItemsContainer != null)
|
||||
{
|
||||
int childCount = spawnedItemsContainer.childCount;
|
||||
if (childCount > 0)
|
||||
{
|
||||
Logging.Debug($"[SortingGameManager] Cleaning up {childCount} items from spawn container");
|
||||
|
||||
for (int i = childCount - 1; i >= 0; i--)
|
||||
{
|
||||
var child = spawnedItemsContainer.GetChild(i);
|
||||
if (child != null)
|
||||
{
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Final safety check: search for any orphaned items in case of edge cases
|
||||
var allItems = FindObjectsByType<SortableItem>(FindObjectsSortMode.None);
|
||||
if (allItems.Length > 0)
|
||||
{
|
||||
Logging.Warning($"[SortingGameManager] Found {allItems.Length} orphaned items, cleaning up...");
|
||||
|
||||
foreach (var item in allItems)
|
||||
{
|
||||
if (item != null && item.gameObject != null)
|
||||
{
|
||||
Logging.Debug($"[SortingGameManager] Destroying orphaned item: {item.CardData?.Name ?? item.GarbageItem?.DisplayName}");
|
||||
Destroy(item.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator EndGameSequence()
|
||||
{
|
||||
// Calculate rewards
|
||||
|
||||
@@ -108,6 +108,13 @@ namespace Minigames.CardSorting.UI
|
||||
|
||||
private async void OnCloseClicked()
|
||||
{
|
||||
// Cleanup all spawned items before transitioning
|
||||
var gameManager = SortingGameManager.Instance;
|
||||
if (gameManager != null)
|
||||
{
|
||||
gameManager.CleanupAllItems();
|
||||
}
|
||||
|
||||
// Hide screen
|
||||
if (canvasGroup != null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user