using System; using System.Collections; using AibisDream.Kit; using AibisDream.SaveSystem; using UnityEngine; namespace AibisDream { /// D2 Sleep 专属动态表现门面;普通静态图片仍由 SpriteShowcase 管理。 public sealed class Day2SleepPresentationController : Singleton { [Header("通用展示引用")] [SerializeField] private SpriteShowcase _showcase; [SerializeField] private SpriteRenderer _smallRenderer; [SerializeField] private SpriteRenderer _largeRenderer; [Header("风筝 / 对焦材质")] [SerializeField] private Material _focusMaterial; [SerializeField] private KiteWindSettings _kiteWindSettings = new(); [SerializeField] private KiteCameraSettings _kiteCameraSettings = new(); [SerializeField] private KiteFocusSettings _kiteFocusSettings = new(); private ReelMotionPresenter _reel; private LargeSpriteEffectsPresenter _largeEffects; private KitePresentation _kite; private Day2SleepPresentationMode _mode; public bool HasPersistableState => _mode != Day2SleepPresentationMode.None; public override void OnSingletonInit() { _showcase ??= SpriteShowcase.Instance; _reel = new ReelMotionPresenter(_smallRenderer); _largeEffects = new LargeSpriteEffectsPresenter(this, _largeRenderer, _focusMaterial); _kite = new KitePresentation( _smallRenderer, _focusMaterial, _kiteWindSettings, _kiteCameraSettings, _kiteFocusSettings); if (_showcase != null) _showcase.PresentationChanging += HandleGenericPresentationChanging; ClearPresentationEffects(); } private void OnDisable() { ClearPresentationEffects(); } public override void OnSingletonDestroy() { if (_showcase != null) _showcase.PresentationChanging -= HandleGenericPresentationChanging; ClearPresentationEffects(); base.OnSingletonDestroy(); } public IEnumerator ShowSpriteMotion(string picName, string motionProfile, float duration = 0.35f) { yield return PrepareExclusiveMode(); yield return _reel.Show(picName, motionProfile); if (_reel.IsShowing) _mode = Day2SleepPresentationMode.SmallMotion; } public void PlayCurrentMotion(string motionProfile) { if (_mode != Day2SleepPresentationMode.SmallMotion) return; _reel.PlayCurrentMotion(motionProfile); } public IEnumerator ShowKite(float height, int wind, float duration = 0.35f) { if (_mode != Day2SleepPresentationMode.Kite) yield return PrepareExclusiveMode(); yield return _kite.Show(height, wind, duration); if (_kite.IsShowing) _mode = Day2SleepPresentationMode.Kite; } public void SetKiteState(float height, int wind, float duration = 0.9f) { _kite.SetState(height, wind, duration); } public void SetKiteWind(int wind, float turbulence = -1f) { _kite.SetWind(wind, turbulence); } public void PlayKiteAccent(string profile) { _kite.PlayAccent(profile); } public IEnumerator HideKite(float duration = 1f) { yield return _kite.Hide(duration); if (_mode == Day2SleepPresentationMode.Kite) _mode = Day2SleepPresentationMode.None; } public IEnumerator ShowLargeSpriteAnimation( string picNamePrefix, int frameCount, float secondsPerFrame = 0.2f, float duration = 1f) { yield return PrepareExclusiveMode(); yield return _largeEffects.ShowAnimation( picNamePrefix, frameCount, secondsPerFrame, duration); if (_largeEffects.IsAnimationPlaying) _mode = Day2SleepPresentationMode.LargeEffects; } public void SetLargeSpriteBlur(float amount, float blurSize = 0.012f) { _largeEffects.SetBlur(amount, blurSize); MarkLargeEffectsActive(); } public IEnumerator TweenLargeSpriteBlur( float targetAmount, float duration, float blurSize = 0.012f) { MarkLargeEffectsActive(); yield return _largeEffects.TweenBlur(targetAmount, duration, blurSize); } public IEnumerator AnimateLargePresentation(float scale, float alpha, float duration) { MarkLargeEffectsActive(); yield return _largeEffects.AnimatePresentation(scale, alpha, duration); } public void SetLargePresentationImmediate(float scale, float alpha) { _largeEffects.ApplyPresentationImmediate(scale, alpha); MarkLargeEffectsActive(); } public void ResetLargePresentationImmediate() { _largeEffects.ResetPresentationImmediate(); } public void StopLargePresentationAnimation() { _largeEffects.StopPresentationAnimation(); } public void HideLargePresentationImmediate() { _largeEffects.HidePresentationImmediate(); if (_mode == Day2SleepPresentationMode.LargeEffects) _mode = Day2SleepPresentationMode.None; } public void SetLargeSpriteImmediate(Sprite sprite) { _largeEffects.SetSpriteImmediate(sprite); } public void ClearPresentationEffects() { _reel?.ClearImmediate(); _kite?.ClearImmediate(); _largeEffects?.ResetEffectsImmediate(); _mode = Day2SleepPresentationMode.None; } public Day2SleepPresentationSnapshotDto CaptureSnapshot() { var snapshot = new Day2SleepPresentationSnapshotDto { mode = _mode.ToString() }; switch (_mode) { case Day2SleepPresentationMode.SmallMotion: snapshot.picName = _reel.CurrentPicName; snapshot.motionProfile = _reel.CurrentMotionProfile; break; case Day2SleepPresentationMode.Kite: snapshot.kiteHeight = _kite.TargetHeight; snapshot.kiteWind = _kite.CurrentWind; snapshot.kiteTurbulence = _kite.Turbulence; break; case Day2SleepPresentationMode.LargeEffects: snapshot.largeAnimationActive = _largeEffects.IsAnimationPlaying; snapshot.largeAnimationPrefix = _largeEffects.AnimationPrefix; snapshot.largeAnimationFrameCount = _largeEffects.AnimationFrameCount; snapshot.largeAnimationSecondsPerFrame = _largeEffects.AnimationSecondsPerFrame; snapshot.largeBlurAmount = _largeEffects.TargetBlurAmount; snapshot.largeBlurSize = _largeEffects.TargetBlurSize; snapshot.largeScaleMultiplier = _largeEffects.TargetScaleMultiplier; snapshot.largeAlpha = _largeEffects.TargetAlpha; break; } return snapshot; } public IEnumerator RestoreSnapshotAsync( Day2SleepPresentationSnapshotDto snapshot, Action warning = null) { ClearPresentationEffects(); if (snapshot == null) yield break; if (!Enum.TryParse(snapshot.mode, true, out Day2SleepPresentationMode mode)) { warning?.Invoke($"[Day2SleepPresentation] Unknown mode: {snapshot.mode}"); yield break; } switch (mode) { case Day2SleepPresentationMode.SmallMotion: if (!string.IsNullOrWhiteSpace(snapshot.picName)) yield return ShowSpriteMotion(snapshot.picName, snapshot.motionProfile, 0f); break; case Day2SleepPresentationMode.Kite: yield return ShowKite(snapshot.kiteHeight, snapshot.kiteWind, 0f); SetKiteWind(snapshot.kiteWind, snapshot.kiteTurbulence); break; case Day2SleepPresentationMode.LargeEffects: if (snapshot.largeAnimationActive && !string.IsNullOrWhiteSpace(snapshot.largeAnimationPrefix) && snapshot.largeAnimationFrameCount > 0) { yield return ShowLargeSpriteAnimation( snapshot.largeAnimationPrefix, snapshot.largeAnimationFrameCount, snapshot.largeAnimationSecondsPerFrame, 0f); } _largeEffects.SetBlur(snapshot.largeBlurAmount, snapshot.largeBlurSize); _largeEffects.ApplyPresentationImmediate( snapshot.largeScaleMultiplier <= 0f ? 1f : snapshot.largeScaleMultiplier, snapshot.largeAlpha); _mode = Day2SleepPresentationMode.LargeEffects; break; } } private IEnumerator PrepareExclusiveMode() { if (_showcase != null) yield return _showcase.HideAll(0f); ClearPresentationEffects(); } private void HandleGenericPresentationChanging() { ClearPresentationEffects(); } private void MarkLargeEffectsActive() { if (_largeRenderer != null && _largeRenderer.gameObject.activeSelf) _mode = Day2SleepPresentationMode.LargeEffects; } } }