Files
bansonic_beta_main/Assets/artworks/gamePlay_gamePlay/321go/readyLetsGo.cs
T

255 lines
8.5 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class readyLetsGo : MonoBehaviour
{
public List<Image> _321goImages;
public GameObject _321goCanvasGO;
public CanvasGroup _321goCanvasgroup;
[Header("duration")]
[SerializeField] float fadeInDuration;
[SerializeField] float fadeOutDuration;
[SerializeField] float displayDuration;
public float oneImageDuration = 1f;
public float waitingDuration = 0.25f;
public float startScale = 1.25f;
public float endScale = 0.8f;
private Coroutine sequenceCoroutine;
// Prevent re-entry / accidental double-play
private bool isPlaying = false;
private float lastPlayedTime = -10f;
[Tooltip("Minimum seconds between automatic replays of the sequence")]
public float replayCooldown = -9999f; // set to negative to prevent replays
// Ensure the sequence only runs once per scene by default
private bool playedOnce = false;
private void Start()
{
// Ensure canvas is hidden initially
if (_321goCanvasGO != null)
{
_321goCanvasGO.SetActive(false);
}
if (_321goCanvasgroup != null)
{
_321goCanvasgroup.alpha = 0;
}
// Ensure all images are inactive at start so they don't flash on scene load.
if (_321goImages != null)
{
for (int i = 0; i < _321goImages.Count; i++)
{
var img = _321goImages[i];
if (img != null && img.gameObject.activeSelf)
{
img.gameObject.SetActive(false);
}
}
}
// reset play state on scene start
isPlaying = false;
lastPlayedTime = -10f;
playedOnce = false; // allow one play when player initiates
}
/// <summary>
/// Play the 3-2-1 GO sequence: fade in canvas, then cycle through images with fade in/out and scaling.
/// Duration calculation: fadeInDuration = fadeOutDuration = oneImageDuration / 5, displayDuration = oneImageDuration * 3 / 5
/// </summary>
public void PlaySequence()
{
// If already played once, do not play again
if (playedOnce) return;
// Prevent immediate replays or re-entrant calls
if (isPlaying)
{
return;
}
if (Time.unscaledTime - lastPlayedTime < replayCooldown)
{
return;
}
// Stop any existing sequence
if (sequenceCoroutine != null)
{
StopCoroutine(sequenceCoroutine);
sequenceCoroutine = null;
}
// Calculate durations based on oneImageDuration
fadeInDuration = oneImageDuration / 5f;
fadeOutDuration = oneImageDuration / 5f;
displayDuration = oneImageDuration * 3f / 5f;
isPlaying = true;
lastPlayedTime = Time.unscaledTime;
sequenceCoroutine = StartCoroutine(PlaySequenceCoroutine());
}
private IEnumerator PlaySequenceCoroutine()
{
// Activate canvas and fade in from alpha 0 to 1 over 0.25 seconds
if (_321goCanvasGO != null)
{
_321goCanvasGO.SetActive(true);
}
if (_321goCanvasgroup != null)
{
float elapsedTime = 0f;
while (elapsedTime < 0.25f)
{
elapsedTime += Time.unscaledDeltaTime;
_321goCanvasgroup.alpha = Mathf.Clamp01(elapsedTime / 0.25f);
yield return null;
}
_321goCanvasgroup.alpha = 1f;
}
// Wait for waitingDuration before starting the image sequence
float waitElapsed = 0f;
while (waitElapsed < waitingDuration)
{
waitElapsed += Time.unscaledDeltaTime;
yield return null;
}
// Cycle through images in the list
for (int i = 0; i < _321goImages.Count; i++)
{
Image currentImage = _321goImages[i];
if (currentImage == null) continue;
// Start the fade in, display, and fade out sequence for this image
yield return StartCoroutine(PlayImageSequence(currentImage));
// After the sequence finishes ensure the image is disabled (PlayImageSequence also disables,
// but keep as defensive measure)
try { if (currentImage != null) currentImage.gameObject.SetActive(false); } catch { }
// If there's a next image, the next loop iteration will activate it when needed
}
// After all images done, hide canvas again
if (_321goCanvasgroup != null)
{
// fade out canvas quickly
float elapsed = 0f;
float duration = 0.15f;
float startA = _321goCanvasgroup.alpha;
while (elapsed < duration)
{
elapsed += Time.unscaledDeltaTime;
float frac = Mathf.Clamp01(elapsed / duration);
_321goCanvasgroup.alpha = Mathf.Lerp(startA, 0f, frac);
yield return null;
}
_321goCanvasgroup.alpha = 0f;
}
if (_321goCanvasGO != null)
{
_321goCanvasGO.SetActive(false);
}
sequenceCoroutine = null;
// mark finished and record time
isPlaying = false;
lastPlayedTime = Time.unscaledTime;
playedOnce = true; // ensure it won't run again unless ResetPlayState is called
}
private IEnumerator PlayImageSequence(Image image)
{
// Ensure the image GameObject is active only for the duration of its display
try
{
if (!image.gameObject.activeSelf)
image.gameObject.SetActive(true);
}
catch { }
// Get the RectTransform for scaling
RectTransform rectTransform = image.GetComponent<RectTransform>();
if (rectTransform == null)
{
// If no rect, still wait whole duration then disable
float fallbackTotal = fadeInDuration + displayDuration + fadeOutDuration;
yield return new WaitForSecondsRealtime(fallbackTotal);
try { image.gameObject.SetActive(false); } catch { }
yield break;
}
// Initialize image alpha to 0 and scale to startScale
Color imageColor = image.color;
imageColor.a = 0f;
image.color = imageColor;
rectTransform.localScale = Vector3.one * startScale;
float totalDuration = fadeInDuration + displayDuration + fadeOutDuration;
float elapsedTime = 0f;
while (elapsedTime < totalDuration)
{
elapsedTime += Time.unscaledDeltaTime;
float normalizedTime = Mathf.Clamp01(elapsedTime / totalDuration);
// Fade in phase (0 to fadeInDuration)
if (elapsedTime < fadeInDuration)
{
float fadeInProgress = elapsedTime / Mathf.Max(0.0001f, fadeInDuration);
imageColor.a = Mathf.Lerp(0f, 1f, fadeInProgress);
}
// Display phase (fadeInDuration to fadeInDuration + displayDuration)
else if (elapsedTime < fadeInDuration + displayDuration)
{
imageColor.a = 1f;
}
// Fade out phase (fadeInDuration + displayDuration to total)
else
{
float fadeOutProgress = (elapsedTime - fadeInDuration - displayDuration) / Mathf.Max(0.0001f, fadeOutDuration);
imageColor.a = Mathf.Lerp(1f, 0f, fadeOutProgress);
}
// Apply alpha
image.color = imageColor;
// Continuous scaling from startScale to endScale throughout the entire sequence
float currentScale = Mathf.Lerp(startScale, endScale, normalizedTime);
rectTransform.localScale = Vector3.one * currentScale;
yield return null;
}
// Ensure final state
imageColor.a = 0f;
image.color = imageColor;
rectTransform.localScale = Vector3.one * endScale;
// Disable the image GameObject after finished to avoid lingering in scene
try { image.gameObject.SetActive(false); } catch { }
}
// Optional public reset if some external system wants to allow replay (e.g., scene reload)
public void ResetPlayState()
{
isPlaying = false;
lastPlayedTime = -10f;
playedOnce = false;
if (sequenceCoroutine != null)
{
try { StopCoroutine(sequenceCoroutine); } catch { }
sequenceCoroutine = null;
}
}
}