Fix card cleanup after dismissing minigame
This commit is contained in:
@@ -159,6 +159,7 @@ MonoBehaviour:
|
|||||||
- {fileID: 731655009}
|
- {fileID: 731655009}
|
||||||
- {fileID: 254614580}
|
- {fileID: 254614580}
|
||||||
- {fileID: 222800744}
|
- {fileID: 222800744}
|
||||||
|
spawnedItemsContainer: {fileID: 330631194}
|
||||||
impulseSource: {fileID: 90351797}
|
impulseSource: {fileID: 90351797}
|
||||||
livesDisplay: {fileID: 934831599}
|
livesDisplay: {fileID: 934831599}
|
||||||
--- !u!4 &90351796
|
--- !u!4 &90351796
|
||||||
@@ -375,6 +376,37 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: a25b1c9a82b540c8ac0d6c016849f561, type: 3}
|
m_Script: {fileID: 11500000, guid: a25b1c9a82b540c8ac0d6c016849f561, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier: AppleHillsScripts::Minigames.CardSorting.Core.SortingBox
|
m_EditorClassIdentifier: AppleHillsScripts::Minigames.CardSorting.Core.SortingBox
|
||||||
|
--- !u!1 &330631193
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 330631194}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: SpawnedItemsTransform
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &330631194
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 330631193}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!224 &425139808 stripped
|
--- !u!224 &425139808 stripped
|
||||||
RectTransform:
|
RectTransform:
|
||||||
m_CorrespondingSourceObject: {fileID: 707190640386266950, guid: acc5a752dcc18834b984fe78b6926dad, type: 3}
|
m_CorrespondingSourceObject: {fileID: 707190640386266950, guid: acc5a752dcc18834b984fe78b6926dad, type: 3}
|
||||||
@@ -499,6 +531,7 @@ GameObject:
|
|||||||
m_IsActive: 1
|
m_IsActive: 1
|
||||||
--- !u!212 &558760374
|
--- !u!212 &558760374
|
||||||
SpriteRenderer:
|
SpriteRenderer:
|
||||||
|
serializedVersion: 2
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
@@ -544,6 +577,7 @@ SpriteRenderer:
|
|||||||
m_SortingLayerID: 622133659
|
m_SortingLayerID: 622133659
|
||||||
m_SortingLayer: -1
|
m_SortingLayer: -1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
|
m_MaskInteraction: 0
|
||||||
m_Sprite: {fileID: -673586258, guid: 91cb3ae9a614f914997704a638d8b514, type: 3}
|
m_Sprite: {fileID: -673586258, guid: 91cb3ae9a614f914997704a638d8b514, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
m_FlipX: 0
|
m_FlipX: 0
|
||||||
@@ -553,7 +587,6 @@ SpriteRenderer:
|
|||||||
m_AdaptiveModeThreshold: 0.5
|
m_AdaptiveModeThreshold: 0.5
|
||||||
m_SpriteTileMode: 0
|
m_SpriteTileMode: 0
|
||||||
m_WasSpriteAssigned: 1
|
m_WasSpriteAssigned: 1
|
||||||
m_MaskInteraction: 0
|
|
||||||
m_SpriteSortPoint: 0
|
m_SpriteSortPoint: 0
|
||||||
--- !u!4 &558760375
|
--- !u!4 &558760375
|
||||||
Transform:
|
Transform:
|
||||||
@@ -1174,6 +1207,7 @@ GameObject:
|
|||||||
m_IsActive: 1
|
m_IsActive: 1
|
||||||
--- !u!212 &1020017634
|
--- !u!212 &1020017634
|
||||||
SpriteRenderer:
|
SpriteRenderer:
|
||||||
|
serializedVersion: 2
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
@@ -1219,6 +1253,7 @@ SpriteRenderer:
|
|||||||
m_SortingLayerID: 622133659
|
m_SortingLayerID: 622133659
|
||||||
m_SortingLayer: -1
|
m_SortingLayer: -1
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
|
m_MaskInteraction: 0
|
||||||
m_Sprite: {fileID: -7171755534009967257, guid: b382c7219ff059c499bdeba018f5a93f, type: 3}
|
m_Sprite: {fileID: -7171755534009967257, guid: b382c7219ff059c499bdeba018f5a93f, type: 3}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
m_FlipX: 0
|
m_FlipX: 0
|
||||||
@@ -1228,7 +1263,6 @@ SpriteRenderer:
|
|||||||
m_AdaptiveModeThreshold: 0.5
|
m_AdaptiveModeThreshold: 0.5
|
||||||
m_SpriteTileMode: 0
|
m_SpriteTileMode: 0
|
||||||
m_WasSpriteAssigned: 1
|
m_WasSpriteAssigned: 1
|
||||||
m_MaskInteraction: 0
|
|
||||||
m_SpriteSortPoint: 0
|
m_SpriteSortPoint: 0
|
||||||
--- !u!4 &1020017635
|
--- !u!4 &1020017635
|
||||||
Transform:
|
Transform:
|
||||||
@@ -2212,5 +2246,6 @@ SceneRoots:
|
|||||||
- {fileID: 558760375}
|
- {fileID: 558760375}
|
||||||
- {fileID: 1020017635}
|
- {fileID: 1020017635}
|
||||||
- {fileID: 1541890084}
|
- {fileID: 1541890084}
|
||||||
|
- {fileID: 330631194}
|
||||||
- {fileID: 621563394}
|
- {fileID: 621563394}
|
||||||
- {fileID: 818930091}
|
- {fileID: 818930091}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace Minigames.CardSorting.Controllers
|
|||||||
private readonly GameObject cardPrefab;
|
private readonly GameObject cardPrefab;
|
||||||
private readonly GameObject garbagePrefab;
|
private readonly GameObject garbagePrefab;
|
||||||
private readonly ICardSortingSettings settings;
|
private readonly ICardSortingSettings settings;
|
||||||
|
private readonly Transform spawnContainer; // Container for all spawned items
|
||||||
|
|
||||||
private List<SortableItem> activeItems = new List<SortableItem>();
|
private List<SortableItem> activeItems = new List<SortableItem>();
|
||||||
private HashSet<SortableItem> missedItems = new HashSet<SortableItem>(); // Items past visual end, moving to despawn
|
private HashSet<SortableItem> missedItems = new HashSet<SortableItem>(); // Items past visual end, moving to despawn
|
||||||
@@ -48,7 +49,8 @@ namespace Minigames.CardSorting.Controllers
|
|||||||
Transform despawnPoint,
|
Transform despawnPoint,
|
||||||
GameObject cardPrefab,
|
GameObject cardPrefab,
|
||||||
GameObject garbagePrefab,
|
GameObject garbagePrefab,
|
||||||
ICardSortingSettings settings)
|
ICardSortingSettings settings,
|
||||||
|
Transform spawnContainer)
|
||||||
{
|
{
|
||||||
this.spawnPoint = spawnPoint;
|
this.spawnPoint = spawnPoint;
|
||||||
this.endPoint = endPoint;
|
this.endPoint = endPoint;
|
||||||
@@ -56,6 +58,7 @@ namespace Minigames.CardSorting.Controllers
|
|||||||
this.cardPrefab = cardPrefab;
|
this.cardPrefab = cardPrefab;
|
||||||
this.garbagePrefab = garbagePrefab;
|
this.garbagePrefab = garbagePrefab;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
this.spawnContainer = spawnContainer;
|
||||||
|
|
||||||
this.currentSpeed = settings.InitialBeltSpeed;
|
this.currentSpeed = settings.InitialBeltSpeed;
|
||||||
this.lastSpawnedItem = null; // No items spawned yet
|
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);
|
float randomOffsetY = Random.Range(settings.SpawnOffsetY.x, settings.SpawnOffsetY.y);
|
||||||
Vector3 spawnPos = spawnPoint.position + new Vector3(0f, randomOffsetY, 0f);
|
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>();
|
SortableItem item = obj.GetComponent<SortableItem>();
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
@@ -212,7 +215,7 @@ namespace Minigames.CardSorting.Controllers
|
|||||||
float randomOffsetY = Random.Range(settings.SpawnOffsetY.x, settings.SpawnOffsetY.y);
|
float randomOffsetY = Random.Range(settings.SpawnOffsetY.x, settings.SpawnOffsetY.y);
|
||||||
Vector3 spawnPos = spawnPoint.position + new Vector3(0f, randomOffsetY, 0f);
|
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>();
|
SortableItem item = obj.GetComponent<SortableItem>();
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
@@ -497,6 +500,39 @@ namespace Minigames.CardSorting.Controllers
|
|||||||
|
|
||||||
Debug.Log("[ConveyorBeltController] Conveyor stopped - all items disabled");
|
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 sortableCardPrefab;
|
||||||
[SerializeField] private GameObject sortableGarbagePrefab;
|
[SerializeField] private GameObject sortableGarbagePrefab;
|
||||||
[SerializeField] private SortingBox[] sortingBoxes;
|
[SerializeField] private SortingBox[] sortingBoxes;
|
||||||
|
[SerializeField] private Transform spawnedItemsContainer; // Container for all spawned items (optional, will auto-create if null)
|
||||||
|
|
||||||
[Header("Effects")]
|
[Header("Effects")]
|
||||||
[SerializeField] private CinemachineImpulseSource impulseSource; // Screen shake on incorrect sort
|
[SerializeField] private CinemachineImpulseSource impulseSource; // Screen shake on incorrect sort
|
||||||
@@ -45,7 +46,8 @@ namespace Minigames.CardSorting.Core
|
|||||||
conveyorDespawnPoint,
|
conveyorDespawnPoint,
|
||||||
sortableCardPrefab,
|
sortableCardPrefab,
|
||||||
sortableGarbagePrefab,
|
sortableGarbagePrefab,
|
||||||
_settings
|
_settings,
|
||||||
|
GetOrCreateSpawnContainer()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Public accessor for states to check game over status
|
// Public accessor for states to check game over status
|
||||||
@@ -91,6 +93,26 @@ namespace Minigames.CardSorting.Core
|
|||||||
Logging.Debug("[SortingGameManager] Initialized with settings");
|
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()
|
internal override void OnManagedStart()
|
||||||
{
|
{
|
||||||
// Subscribe to score events
|
// Subscribe to score events
|
||||||
@@ -247,6 +269,54 @@ namespace Minigames.CardSorting.Core
|
|||||||
StartCoroutine(EndGameSequence());
|
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()
|
private IEnumerator EndGameSequence()
|
||||||
{
|
{
|
||||||
// Calculate rewards
|
// Calculate rewards
|
||||||
|
|||||||
@@ -108,6 +108,13 @@ namespace Minigames.CardSorting.UI
|
|||||||
|
|
||||||
private async void OnCloseClicked()
|
private async void OnCloseClicked()
|
||||||
{
|
{
|
||||||
|
// Cleanup all spawned items before transitioning
|
||||||
|
var gameManager = SortingGameManager.Instance;
|
||||||
|
if (gameManager != null)
|
||||||
|
{
|
||||||
|
gameManager.CleanupAllItems();
|
||||||
|
}
|
||||||
|
|
||||||
// Hide screen
|
// Hide screen
|
||||||
if (canvasGroup != null)
|
if (canvasGroup != null)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user