成就系统 巨大修改 新的ui 黑白效果 等一堆
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user