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;
}
}
}