using UnityEngine; using Pooling; namespace Minigames.DivingForPictures { /// /// Represents a single bubble, handling its movement, wobble effect, scaling, and sprite assignment. /// public class Bubble : MonoBehaviour, IPoolableWithReference { public float speed = 1f; public float wobbleSpeed = 1f; private SpriteRenderer spriteRenderer; private SpriteRenderer bubbleSpriteRenderer; // Renamed from bottleSpriteRenderer private float timeOffset; private float minScale = 0.2f; private float maxScale = 1.2f; private float baseScale = 1f; // Added to store the initial scale private Camera mainCamera; // Cache camera reference private BubblePool parentPool; // Reference to the pool this bubble came from void Awake() { // Cache references and randomize time offset for wobble spriteRenderer = GetComponent(); timeOffset = Random.value * 100f; // Find the child named "BubbleSprite" and get its SpriteRenderer Transform bubbleSpriteTransform = transform.Find("BubbleSprite"); if (bubbleSpriteTransform != null) { bubbleSpriteRenderer = bubbleSpriteTransform.GetComponent(); } // Cache camera reference mainCamera = Camera.main; } void Update() { // Move bubble upward transform.position += Vector3.up * (speed * Time.deltaTime); // Wobble effect (smooth oscillation between min and max scale) float t = (Mathf.Sin((Time.time + timeOffset) * wobbleSpeed) + 1f) * 0.5f; // t in [0,1] float wobbleFactor = Mathf.Lerp(minScale, maxScale, t); transform.localScale = Vector3.one * (baseScale * wobbleFactor); // Destroy when off screen - using cached camera reference if (mainCamera != null && transform.position.y > mainCamera.orthographicSize + 2f) { OnBubbleDestroy(); } } /// /// Called when bubble is about to be destroyed /// private void OnBubbleDestroy() { // Use the cached pool reference instead of finding it each time if (parentPool != null) { parentPool.ReturnBubble(this); } else { // Fallback to find the pool if the reference is somehow lost BubblePool pool = FindFirstObjectByType(); if (pool != null) { Debug.LogWarning("Bubble is missing its parent pool reference, finding pool as fallback"); pool.ReturnBubble(this); } else { Destroy(gameObject); } } } /// /// Sets the parent pool for this bubble /// /// The bubble pool that created this bubble public void SetPool(BubblePool pool) { parentPool = pool; } /// /// Called when the object is retrieved from the pool. /// public void OnSpawn() { ResetState(); } /// /// Called when the object is returned to the pool. /// public void OnDespawn() { // Nothing to do here for now, but we could clean up resources } /// /// Sets the main sprite for the bubble. /// /// Sprite to assign. public void SetSprite(Sprite sprite) { if (spriteRenderer != null) spriteRenderer.sprite = sprite; } /// /// Sets the sprite for the child "BubbleSprite" renderer. /// /// Sprite to assign. public void SetBubbleSprite(Sprite sprite) { if (bubbleSpriteRenderer != null) bubbleSpriteRenderer.sprite = sprite; } /// /// Sets the base scale for the bubble /// /// Base scale value public void SetBaseScale(float scale) { baseScale = scale; } /// /// Sets the minimum and maximum scale for the wobble effect. /// /// Minimum scale. /// Maximum scale. public void SetWobbleScaleLimits(float min, float max) { minScale = min; maxScale = max; } /// /// Resets the bubble state for reuse from object pool /// public void ResetState() { timeOffset = Random.value * 100f; } } }