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 FallKiteOutOfFrame(float duration = 1.1f)
{
yield return _kite.FallOutOfFrame(duration);
}
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;
}
}
}