using UnityEngine; using System.Collections; namespace Minigames.DivingForPictures { /// /// Handles visual feedback for player damage by making the sprite renderer blink red. /// Automatically subscribes to damage events from PlayerCollisionBehavior components. /// public class PlayerBlinkBehavior : MonoBehaviour { [Header("Blink Settings")] [Tooltip("Color to blink to when taking damage (typically red for damage indication)")] [SerializeField] private Color damageBlinkColor = Color.red; [Tooltip("How fast to blink between normal and damage colors (seconds between color changes)")] [SerializeField] private float blinkRate = 0.15f; [Tooltip("Alpha value for the damage color (0 = transparent, 1 = opaque)")] [Range(0f, 1f)] [SerializeField] private float damageColorAlpha = 0.7f; [Header("References")] [Tooltip("The SpriteRenderer to apply blink effects to (auto-assigned if empty)")] [SerializeField] private SpriteRenderer targetSpriteRenderer; private bool _isBlinking; private bool _isShowingDamageColor; private Coroutine _blinkCoroutine; private Color _originalColor; // Missing field declaration private void Awake() { // Auto-assign sprite renderer if not set if (targetSpriteRenderer == null) { targetSpriteRenderer = GetComponent(); if (targetSpriteRenderer == null) { targetSpriteRenderer = GetComponentInChildren(); if (targetSpriteRenderer != null) { Debug.Log($"[PlayerBlinkBehavior] Found SpriteRenderer on child object: {targetSpriteRenderer.gameObject.name}"); } } } if (targetSpriteRenderer == null) { Debug.LogError("[PlayerBlinkBehavior] No SpriteRenderer found on this GameObject or its children!"); return; } // Store original color _originalColor = targetSpriteRenderer.color; // Ensure damage color has the correct alpha damageBlinkColor.a = damageColorAlpha; } private void OnEnable() { // Subscribe to immunity events (renamed from damage events) PlayerCollisionBehavior.OnImmunityStarted += StartBlinking; PlayerCollisionBehavior.OnImmunityEnded += StopBlinking; } private void OnDisable() { // Unsubscribe from immunity events PlayerCollisionBehavior.OnImmunityStarted -= StartBlinking; PlayerCollisionBehavior.OnImmunityEnded -= StopBlinking; // Stop any ongoing blink effect if (_blinkCoroutine != null) { StopCoroutine(_blinkCoroutine); _blinkCoroutine = null; } // Restore original color RestoreOriginalColor(); } /// /// Starts the red blinking effect when damage begins /// private void StartBlinking() { if (targetSpriteRenderer == null) return; Debug.Log("[PlayerBlinkBehavior] Starting damage blink effect"); // Stop any existing blink coroutine if (_blinkCoroutine != null) { StopCoroutine(_blinkCoroutine); } _isBlinking = true; _isShowingDamageColor = false; // Start the blink coroutine _blinkCoroutine = StartCoroutine(BlinkCoroutine()); } /// /// Stops the blinking effect when damage ends /// private void StopBlinking() { Debug.Log("[PlayerBlinkBehavior] Stopping damage blink effect"); _isBlinking = false; // Stop the blink coroutine if (_blinkCoroutine != null) { StopCoroutine(_blinkCoroutine); _blinkCoroutine = null; } // Restore original color RestoreOriginalColor(); } /// /// Coroutine that handles the blinking animation /// private IEnumerator BlinkCoroutine() { while (_isBlinking && targetSpriteRenderer != null) { // Toggle between original and damage colors if (_isShowingDamageColor) { targetSpriteRenderer.color = _originalColor; _isShowingDamageColor = false; } else { targetSpriteRenderer.color = damageBlinkColor; _isShowingDamageColor = true; } // Wait for blink interval yield return new WaitForSeconds(blinkRate); } } /// /// Restores the sprite renderer to its original color /// private void RestoreOriginalColor() { if (targetSpriteRenderer != null) { targetSpriteRenderer.color = _originalColor; _isShowingDamageColor = false; } } /// /// Updates the original color reference (useful if sprite color changes during gameplay) /// public void UpdateOriginalColor() { if (targetSpriteRenderer != null && !_isBlinking) { _originalColor = targetSpriteRenderer.color; } } /// /// Public method to change blink color at runtime /// public void SetDamageBlinkColor(Color newColor) { damageBlinkColor = newColor; damageBlinkColor.a = damageColorAlpha; } /// /// Public method to change blink rate at runtime /// public void SetBlinkRate(float rate) { blinkRate = rate; } /// /// Check if currently blinking /// public bool IsBlinking => _isBlinking; /// /// Manually trigger blink effect (useful for testing or other damage sources) /// public void TriggerBlink(float duration) { if (_blinkCoroutine != null) { StopCoroutine(_blinkCoroutine); } StartCoroutine(ManualBlinkCoroutine(duration)); } /// /// Coroutine for manually triggered blink effects /// private IEnumerator ManualBlinkCoroutine(float duration) { _isBlinking = true; _isShowingDamageColor = false; float elapsed = 0f; while (elapsed < duration && targetSpriteRenderer != null) { // Toggle between original and damage colors if (_isShowingDamageColor) { targetSpriteRenderer.color = _originalColor; _isShowingDamageColor = false; } else { targetSpriteRenderer.color = damageBlinkColor; _isShowingDamageColor = true; } yield return new WaitForSeconds(blinkRate); elapsed += blinkRate; } // Ensure we end with original color RestoreOriginalColor(); _isBlinking = false; } } }