using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace AibisDream.MiniGame.HuoShan
{
///
/// 火山剧情 - 波形显示系统
/// 负责管理波形的显示、变换和比对
///
public class WaveformDisplaySystem : MonoBehaviour
{
#region 单例
private static WaveformDisplaySystem _instance;
public static WaveformDisplaySystem Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType();
}
return _instance;
}
}
#endregion
#region 序列化字段
[Header("波形显示容器")]
[SerializeField] private RectTransform waveformContainer;
[SerializeField] private CanvasGroup waveformCanvasGroup;
[Header("波形图像")]
[SerializeField] private Image primaryWaveformImage;
[SerializeField] private Image secondaryWaveformImage; // 用于比对模式
[Header("步进进度")]
[SerializeField] private GameObject stepProgressPanel;
[SerializeField] private Text stepProgressText;
[SerializeField] private Slider stepProgressSlider;
[Header("报错效果")]
[SerializeField] private RectTransform errorContainer;
[SerializeField] private GameObject errorPrefab;
[SerializeField] private int maxErrorCount = 10;
[Header("波形资源")]
[SerializeField] private WaveformData[] waveformDataList;
#endregion
#region 私有字段
private Dictionary _waveformDict;
private List _activeErrors = new List();
private Coroutine _currentAnimation;
#endregion
#region 生命周期
private void Awake()
{
_instance = this;
InitializeWaveformDictionary();
}
private void OnDestroy()
{
if (_instance == this)
{
_instance = null;
}
}
private void InitializeWaveformDictionary()
{
_waveformDict = new Dictionary();
if (waveformDataList != null)
{
foreach (var data in waveformDataList)
{
if (!string.IsNullOrEmpty(data.waveformId))
{
_waveformDict[data.waveformId] = data;
}
}
}
}
#endregion
#region 波形显示
///
/// 显示波形
///
public IEnumerator ShowWaveform(string waveformType, float duration)
{
if (_waveformDict.TryGetValue(waveformType, out var data))
{
primaryWaveformImage.sprite = data.waveformSprite;
primaryWaveformImage.color = data.waveformColor;
if (waveformContainer != null)
{
waveformContainer.gameObject.SetActive(true);
}
// 淡入动画
yield return FadeWaveform(0f, 1f, duration);
}
else
{
Debug.LogWarning($"WaveformDisplaySystem: 未找到波形类型 '{waveformType}'");
}
}
///
/// 隐藏波形
///
public IEnumerator HideWaveform(float duration)
{
yield return FadeWaveform(1f, 0f, duration);
if (waveformContainer != null)
{
waveformContainer.gameObject.SetActive(false);
}
}
///
/// 波形淡入淡出
///
private IEnumerator FadeWaveform(float from, float to, float duration)
{
if (waveformCanvasGroup == null) yield break;
float elapsed = 0f;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
waveformCanvasGroup.alpha = Mathf.Lerp(from, to, elapsed / duration);
yield return null;
}
waveformCanvasGroup.alpha = to;
}
#endregion
#region 波形变换
///
/// 波形变换动画
///
public IEnumerator TransformWaveform(string fromType, string toType, float duration)
{
if (!_waveformDict.TryGetValue(fromType, out var fromData) ||
!_waveformDict.TryGetValue(toType, out var toData))
{
Debug.LogWarning($"WaveformDisplaySystem: 波形变换失败,未找到波形类型");
yield break;
}
// 显示原始波形
primaryWaveformImage.sprite = fromData.waveformSprite;
primaryWaveformImage.color = fromData.waveformColor;
if (waveformContainer != null)
{
waveformContainer.gameObject.SetActive(true);
}
yield return FadeWaveform(0f, 1f, duration * 0.2f);
// 变换动画
float elapsed = 0f;
float transformDuration = duration * 0.6f;
while (elapsed < transformDuration)
{
elapsed += Time.deltaTime;
float t = elapsed / transformDuration;
// 颜色插值
primaryWaveformImage.color = Color.Lerp(fromData.waveformColor, toData.waveformColor, t);
// 可以添加更多变换效果,如缩放、抖动等
float shake = Mathf.Sin(t * Mathf.PI * 10) * (1 - t) * 5f;
if (primaryWaveformImage.rectTransform != null)
{
primaryWaveformImage.rectTransform.localPosition = new Vector3(shake, 0, 0);
}
yield return null;
}
// 切换到目标波形
primaryWaveformImage.sprite = toData.waveformSprite;
primaryWaveformImage.color = toData.waveformColor;
if (primaryWaveformImage.rectTransform != null)
{
primaryWaveformImage.rectTransform.localPosition = Vector3.zero;
}
yield return new WaitForSeconds(duration * 0.2f);
}
#endregion
#region 波形比对
///
/// 波形比对显示
///
public IEnumerator CompareWaveforms(string waveform1, string waveform2)
{
if (!_waveformDict.TryGetValue(waveform1, out var data1) ||
!_waveformDict.TryGetValue(waveform2, out var data2))
{
Debug.LogWarning($"WaveformDisplaySystem: 波形比对失败,未找到波形类型");
yield break;
}
primaryWaveformImage.sprite = data1.waveformSprite;
primaryWaveformImage.color = data1.waveformColor;
if (secondaryWaveformImage != null)
{
secondaryWaveformImage.gameObject.SetActive(true);
secondaryWaveformImage.sprite = data2.waveformSprite;
secondaryWaveformImage.color = data2.waveformColor;
}
if (waveformContainer != null)
{
waveformContainer.gameObject.SetActive(true);
}
yield return FadeWaveform(0f, 1f, 0.3f);
}
#endregion
#region 步进进度
///
/// 显示步进进度
///
public void ShowStepProgress(int currentStep, int totalSteps)
{
if (stepProgressPanel != null)
{
stepProgressPanel.SetActive(true);
}
UpdateStepProgress(currentStep);
if (stepProgressSlider != null)
{
stepProgressSlider.maxValue = totalSteps;
}
}
///
/// 更新步进进度
///
public void UpdateStepProgress(int currentStep)
{
if (stepProgressText != null)
{
stepProgressText.text = $"Step {currentStep}";
}
if (stepProgressSlider != null)
{
stepProgressSlider.value = currentStep;
}
}
///
/// 隐藏步进进度
///
public void HideStepProgress()
{
if (stepProgressPanel != null)
{
stepProgressPanel.SetActive(false);
}
}
#endregion
#region 报错效果
///
/// 显示连续报错
///
public IEnumerator ShowErrorFlood(string[] errorMessages, int count, float interval)
{
for (int i = 0; i < count && i < errorMessages.Length; i++)
{
SpawnError(errorMessages[i % errorMessages.Length]);
yield return new WaitForSeconds(interval);
}
}
///
/// 生成单个报错
///
private void SpawnError(string message)
{
if (errorPrefab == null || errorContainer == null) return;
// 限制报错数量
while (_activeErrors.Count >= maxErrorCount)
{
var oldest = _activeErrors[0];
_activeErrors.RemoveAt(0);
Destroy(oldest);
}
var errorObj = Instantiate(errorPrefab, errorContainer);
var errorText = errorObj.GetComponentInChildren();
if (errorText != null)
{
errorText.text = message;
}
// 随机位置偏移
var rect = errorObj.GetComponent();
if (rect != null)
{
rect.anchoredPosition = new Vector2(
Random.Range(-50f, 50f),
Random.Range(-30f, 30f)
);
}
_activeErrors.Add(errorObj);
}
///
/// 清除所有报错
///
public void ClearErrors()
{
foreach (var error in _activeErrors)
{
if (error != null)
{
Destroy(error);
}
}
_activeErrors.Clear();
}
#endregion
}
///
/// 波形数据
///
[System.Serializable]
public class WaveformData
{
[Tooltip("波形ID,用于在Yarn脚本中引用")]
public string waveformId;
[Tooltip("波形图像")]
public Sprite waveformSprite;
[Tooltip("波形颜色")]
public Color waveformColor = Color.cyan;
[Tooltip("波形描述")]
public string description;
}
}