Add a pausable interface and make minigameobjecs pausable

This commit is contained in:
Michal Pikulski
2025-10-08 12:36:08 +02:00
parent 3807ac652c
commit 0e17516df7
11 changed files with 1101 additions and 395 deletions

View File

@@ -3,6 +3,7 @@ using System.Collections;
using AppleHills.Core.Settings;
using Pooling;
using Utils;
using AppleHills.Core.Interfaces;
namespace Minigames.DivingForPictures
{
@@ -12,7 +13,7 @@ namespace Minigames.DivingForPictures
/// Once an obstacle hits the player, its collider is disabled to prevent further collisions.
/// Uses coroutines for better performance instead of Update() calls.
/// </summary>
public class FloatingObstacle : MonoBehaviour, IPoolable
public class FloatingObstacle : MonoBehaviour, IPoolable, IPausable
{
[Header("Obstacle Properties")]
[Tooltip("Index of the prefab this obstacle was created from")]
@@ -57,6 +58,12 @@ namespace Minigames.DivingForPictures
private float _screenNormalizationFactor = 1.0f;
private IDivingMinigameSettings _settings;
// Pause state
private bool _isPaused = false;
// IPausable implementation
public bool IsPaused => _isPaused;
private void Awake()
{
_collider = GetComponent<Collider2D>();
@@ -115,31 +122,67 @@ namespace Minigames.DivingForPictures
private void OnEnable()
{
StartObstacleBehavior();
// Only start coroutines if not paused
if (!_isPaused)
{
StartObstacleCoroutines();
}
// Screen bounds are calculated in CheckIfOffScreen method
}
private void OnDisable()
{
StopObstacleBehavior();
// Stop coroutines when disabled
StopObstacleCoroutines();
}
/// <summary>
/// Starts the obstacle behavior coroutines
/// Pause this obstacle's movement and behavior
/// </summary>
private void StartObstacleBehavior()
public void Pause()
{
if (enableMovement)
if (_isPaused) return; // Already paused
_isPaused = true;
StopObstacleCoroutines();
Debug.Log($"[FloatingObstacle] Paused obstacle: {name}");
}
/// <summary>
/// Resume this obstacle's movement and behavior
/// </summary>
public void Resume()
{
if (!_isPaused) return; // Already running
_isPaused = false;
StartObstacleCoroutines();
Debug.Log($"[FloatingObstacle] Resumed obstacle: {name}");
}
/// <summary>
/// Start all coroutines used by this obstacle
/// </summary>
private void StartObstacleCoroutines()
{
if (enableMovement && _movementCoroutine == null)
{
_movementCoroutine = StartCoroutine(MovementCoroutine());
}
_offScreenCheckCoroutine = StartCoroutine(OffScreenCheckCoroutine());
if (_offScreenCheckCoroutine == null)
{
_offScreenCheckCoroutine = StartCoroutine(OffScreenCheckCoroutine());
}
}
/// <summary>
/// Stops all obstacle behavior coroutines
/// Stop all coroutines used by this obstacle
/// </summary>
private void StopObstacleBehavior()
private void StopObstacleCoroutines()
{
if (_movementCoroutine != null)
{
@@ -270,7 +313,7 @@ namespace Minigames.DivingForPictures
{
// CRITICAL: Stop all behavior first to prevent race conditions
// This ensures no more off-screen checks or movement happen during pool return
StopObstacleBehavior();
StopObstacleCoroutines();
if (spawner != null)
{
@@ -333,7 +376,7 @@ namespace Minigames.DivingForPictures
public void OnDespawn()
{
// Stop all coroutines before returning to pool
StopObstacleBehavior();
StopObstacleCoroutines();
// Re-enable collider for next use (in case it was disabled)
if (_collider != null)
@@ -364,8 +407,8 @@ namespace Minigames.DivingForPictures
// Restart coroutines to apply movement change
if (gameObject.activeInHierarchy)
{
StopObstacleBehavior();
StartObstacleBehavior();
StopObstacleCoroutines();
StartObstacleCoroutines();
}
}