222 lines
6.4 KiB
C#
222 lines
6.4 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class IntroTitleSequence : MonoBehaviour
|
|
{
|
|
[System.Serializable]
|
|
public class IntroSequenceItem
|
|
{
|
|
[Header("Info")]
|
|
public string itemName;
|
|
|
|
[Header("Target")]
|
|
public GameObject target;
|
|
|
|
[Header("Timing")]
|
|
public float delay = 0f;
|
|
public float fadeDuration = 0.6f;
|
|
|
|
[Header("Appear Motion")]
|
|
[Range(0.1f, 1f)]
|
|
public float startScaleRatio = 0.92f;
|
|
|
|
public Vector3 startOffset = new Vector3(0f, -0.08f, 0f);
|
|
|
|
[Header("After Appear")]
|
|
public bool enableFloatingAfterAppear = true;
|
|
public bool enableParallaxAfterAppear = true;
|
|
public bool enableButtonPulseAfterAppear = false;
|
|
}
|
|
|
|
[Header("Sequence")]
|
|
public bool playOnStart = true;
|
|
public float globalDelayMultiplier = 1f;
|
|
public float globalFadeMultiplier = 1f;
|
|
public List<IntroSequenceItem> sequenceItems = new List<IntroSequenceItem>();
|
|
|
|
[Header("Optional Particle")]
|
|
public ParticleSystem petalParticle;
|
|
public float petalStartDelay = 0.2f;
|
|
|
|
private readonly Dictionary<GameObject, Vector3> originalPositions = new Dictionary<GameObject, Vector3>();
|
|
private readonly Dictionary<GameObject, Vector3> originalScales = new Dictionary<GameObject, Vector3>();
|
|
|
|
private void Start()
|
|
{
|
|
if (playOnStart)
|
|
{
|
|
PlaySequence();
|
|
}
|
|
}
|
|
|
|
public void PlaySequence()
|
|
{
|
|
StopAllCoroutines();
|
|
|
|
CacheOriginalTransforms();
|
|
PrepareAllItems();
|
|
|
|
StartCoroutine(PlaySequenceRoutine());
|
|
}
|
|
|
|
private void CacheOriginalTransforms()
|
|
{
|
|
originalPositions.Clear();
|
|
originalScales.Clear();
|
|
|
|
foreach (IntroSequenceItem item in sequenceItems)
|
|
{
|
|
if (item == null || item.target == null)
|
|
continue;
|
|
|
|
originalPositions[item.target] = item.target.transform.localPosition;
|
|
originalScales[item.target] = item.target.transform.localScale;
|
|
}
|
|
}
|
|
|
|
private void PrepareAllItems()
|
|
{
|
|
foreach (IntroSequenceItem item in sequenceItems)
|
|
{
|
|
if (item == null || item.target == null)
|
|
continue;
|
|
|
|
GameObject target = item.target;
|
|
|
|
target.SetActive(true);
|
|
|
|
Vector3 originalPosition = originalPositions[target];
|
|
Vector3 originalScale = originalScales[target];
|
|
|
|
target.transform.localPosition = originalPosition + item.startOffset;
|
|
target.transform.localScale = originalScale * item.startScaleRatio;
|
|
|
|
SetTargetAlpha(target, 0f);
|
|
|
|
SetOptionalMotionScripts(target, false, false, false);
|
|
}
|
|
}
|
|
|
|
private IEnumerator PlaySequenceRoutine()
|
|
{
|
|
if (petalParticle != null)
|
|
{
|
|
petalParticle.Stop();
|
|
|
|
if (petalStartDelay > 0f)
|
|
yield return new WaitForSeconds(petalStartDelay);
|
|
|
|
petalParticle.Play();
|
|
}
|
|
|
|
foreach (IntroSequenceItem item in sequenceItems)
|
|
{
|
|
if (item == null || item.target == null)
|
|
continue;
|
|
|
|
StartCoroutine(AppearRoutine(item));
|
|
}
|
|
}
|
|
|
|
private IEnumerator AppearRoutine(IntroSequenceItem item)
|
|
{
|
|
float delay = Mathf.Max(0f, item.delay * globalDelayMultiplier);
|
|
float duration = Mathf.Max(0.01f, item.fadeDuration * globalFadeMultiplier);
|
|
|
|
if (delay > 0f)
|
|
yield return new WaitForSeconds(delay);
|
|
|
|
GameObject target = item.target;
|
|
|
|
Vector3 originalPosition = originalPositions[target];
|
|
Vector3 originalScale = originalScales[target];
|
|
|
|
Vector3 startPosition = originalPosition + item.startOffset;
|
|
Vector3 startScale = originalScale * item.startScaleRatio;
|
|
|
|
target.transform.localPosition = startPosition;
|
|
target.transform.localScale = startScale;
|
|
SetTargetAlpha(target, 0f);
|
|
|
|
float elapsed = 0f;
|
|
|
|
while (elapsed < duration)
|
|
{
|
|
elapsed += Time.deltaTime;
|
|
|
|
float t = Mathf.Clamp01(elapsed / duration);
|
|
float easedT = EaseOutCubic(t);
|
|
|
|
SetTargetAlpha(target, easedT);
|
|
|
|
target.transform.localPosition = Vector3.Lerp(startPosition, originalPosition, easedT);
|
|
target.transform.localScale = Vector3.Lerp(startScale, originalScale, easedT);
|
|
|
|
yield return null;
|
|
}
|
|
|
|
SetTargetAlpha(target, 1f);
|
|
target.transform.localPosition = originalPosition;
|
|
target.transform.localScale = originalScale;
|
|
|
|
SetOptionalMotionScripts(
|
|
target,
|
|
item.enableFloatingAfterAppear,
|
|
item.enableParallaxAfterAppear,
|
|
item.enableButtonPulseAfterAppear
|
|
);
|
|
}
|
|
|
|
private void SetTargetAlpha(GameObject target, float alpha)
|
|
{
|
|
SpriteRenderer[] spriteRenderers = target.GetComponentsInChildren<SpriteRenderer>(true);
|
|
foreach (SpriteRenderer sr in spriteRenderers)
|
|
{
|
|
Color color = sr.color;
|
|
color.a = alpha;
|
|
sr.color = color;
|
|
}
|
|
|
|
Graphic[] graphics = target.GetComponentsInChildren<Graphic>(true);
|
|
foreach (Graphic graphic in graphics)
|
|
{
|
|
Color color = graphic.color;
|
|
color.a = alpha;
|
|
graphic.color = color;
|
|
}
|
|
|
|
CanvasGroup[] canvasGroups = target.GetComponentsInChildren<CanvasGroup>(true);
|
|
foreach (CanvasGroup canvasGroup in canvasGroups)
|
|
{
|
|
canvasGroup.alpha = alpha;
|
|
}
|
|
}
|
|
|
|
private void SetOptionalMotionScripts(GameObject target, bool floating, bool parallax, bool buttonPulse)
|
|
{
|
|
IntroFloatingLayer[] floatingLayers = target.GetComponentsInChildren<IntroFloatingLayer>(true);
|
|
foreach (IntroFloatingLayer layer in floatingLayers)
|
|
{
|
|
layer.enabled = floating;
|
|
}
|
|
|
|
IntroParallaxLayer[] parallaxLayers = target.GetComponentsInChildren<IntroParallaxLayer>(true);
|
|
foreach (IntroParallaxLayer layer in parallaxLayers)
|
|
{
|
|
layer.enabled = parallax;
|
|
}
|
|
|
|
IntroButtonPulse[] buttonPulses = target.GetComponentsInChildren<IntroButtonPulse>(true);
|
|
foreach (IntroButtonPulse pulse in buttonPulses)
|
|
{
|
|
pulse.enabled = buttonPulse;
|
|
}
|
|
}
|
|
|
|
private float EaseOutCubic(float t)
|
|
{
|
|
return 1f - Mathf.Pow(1f - t, 3f);
|
|
}
|
|
} |