using System.Collections;
using UnityEngine;
using DG.Tweening;
using AibisDream.FixSystem;
namespace AibisDream.MiniGame.HuoShan.EmotionWave
{
///
/// 情绪波形管理器 - 用于控制情绪波形的显示、隐藏和进度动画
///
/// 功能:
/// - FixSystemCenter 注册/注销
/// - DOTween 显示/隐藏动画
/// - 进度控制:立即设置 + 平滑动画
/// - 平滑追踪:smoothstep lerp 追踪目标进度
///
public class EmotionWaveManager : MonoBehaviour
{
#region 序列化字段
[Header("References")]
[SerializeField] private EmotionWaveController controller;
[SerializeField] private Transform containerTransform;
[Header("Slider Sync")]
[Tooltip("可选:关联 SliderController 以自动同步进度")]
[SerializeField] private SliderController sliderController;
[Tooltip("是否启用滑片同步(勾选后滑片进度会自动驱动情绪波形进度)")]
[SerializeField] private bool enableSliderSync = true;
[Header("动画设置")]
[SerializeField] private Vector2 hiddenPosition = new Vector2(0f, -600f);
[SerializeField] private Vector2 shownPosition = new Vector2(0f, 0f);
[SerializeField] private float showDuration = 0.5f;
[SerializeField] private float hideDuration = 0.3f;
[SerializeField] private Ease showEase = Ease.OutCubic;
[SerializeField] private Ease hideEase = Ease.InCubic;
[Header("Progress Settings")]
[SerializeField] private float lerpSpeed = 4f;
[Header("Debug")]
[SerializeField] [ReadOnly] private float currentProgress;
[SerializeField] [ReadOnly] private float targetProgress;
[SerializeField] [ReadOnly] private bool isShown;
#endregion
#region 私有字段
private Tweener _progressTweener;
private string _currentPresetId = "normal";
private AudioSource _audioSource;
#endregion
#region 预设
public string CurrentPresetId => _currentPresetId;
///
/// 切换波形预设(normal / predicted / modified_joke / empty)
/// empty 为低存在感待机态,会保留极弱噪波
///
public void SetPreset(string presetId)
{
if (string.IsNullOrEmpty(presetId)) return;
_currentPresetId = presetId;
if (controller != null)
controller.SetPreset(presetId);
}
#endregion
#region 属性
public bool IsShown => isShown;
public float CurrentProgress => currentProgress;
public float TargetProgress => targetProgress;
#endregion
#region 生命周期
private void Awake()
{
_audioSource = GetComponent();
if (_audioSource == null)
{
_audioSource = gameObject.AddComponent();
}
// 初始化位置为隐藏状态(不控制 scale,由场景/Prefab 决定)
if (containerTransform != null)
{
containerTransform.localPosition = hiddenPosition;
}
// 注册到 FixSystemCenter
FixSystemCenter.SystemDic.Register(this);
// 订阅 SliderController 的进度事件
if (sliderController != null && enableSliderSync)
{
sliderController.onSliderPositionChanged.AddListener(OnSliderPositionChanged);
}
}
private void OnDestroy()
{
// 清理 DOTween
_progressTweener?.Kill();
// 取消订阅
if (sliderController != null)
{
sliderController.onSliderPositionChanged.RemoveListener(OnSliderPositionChanged);
}
// 注销
FixSystemCenter.SystemDic.Unregister();
}
private void Update()
{
if (controller == null) return;
// smoothstep lerp 追踪目标进度(和 Web 版 lerpSpeed = 4.0 一致)
float dt = Time.deltaTime;
currentProgress += (targetProgress - currentProgress) * Mathf.Min(1f, dt * lerpSpeed);
// 将当前进度传递给 Controller
controller.Progress = currentProgress;
}
#endregion
#region 显示/隐藏动画
///
/// 显示情绪波形(DOTween 动画)
///
public IEnumerator Show(float duration = -1f)
{
if (isShown) yield break;
float actualDuration = duration > 0 ? duration : showDuration;
isShown = true;
if (containerTransform != null)
{
yield return containerTransform.DOLocalMove(shownPosition, actualDuration)
.SetEase(showEase)
.WaitForCompletion();
}
}
///
/// 隐藏情绪波形(DOTween 动画)
///
public IEnumerator Hide(float duration = -1f)
{
if (!isShown) yield break;
float actualDuration = duration > 0 ? duration : hideDuration;
isShown = false;
// 停止所有进度动画
_progressTweener?.Kill();
if (containerTransform != null)
{
yield return containerTransform.DOLocalMove(hiddenPosition, actualDuration)
.SetEase(hideEase)
.WaitForCompletion();
}
}
#endregion
#region 进度控制
///
/// 立即设置进度(不等待)
///
public void SetProgress(float value)
{
_progressTweener?.Kill();
targetProgress = Mathf.Clamp01(value);
currentProgress = targetProgress;
}
///
/// 动画到指定进度(DOTween 驱动 targetProgress)
///
public IEnumerator AnimateToProgress(float target, float duration)
{
_progressTweener?.Kill();
target = Mathf.Clamp01(target);
// 使用 DOTween.To 驱动 targetProgress
_progressTweener = DOTween.To(
() => targetProgress,
x => targetProgress = x,
target,
duration
).SetEase(Ease.InOutCubic);
yield return _progressTweener.WaitForCompletion();
}
#endregion
#region Slider 同步
///
/// 响应 SliderController 的位置变化事件
///
private void OnSliderPositionChanged(float normalizedPosition)
{
if (!enableSliderSync) return;
// 滑片进度直接驱动 targetProgress(平滑追踪会在 Update 中处理)
targetProgress = Mathf.Clamp01(normalizedPosition);
}
///
/// 启用/禁用滑片同步
///
public void SetSliderSyncEnabled(bool enabled)
{
enableSliderSync = enabled;
}
#endregion
#region 辅助方法
[System.Serializable]
private class ReadOnlyAttribute : PropertyAttribute { }
#endregion
}
}