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; } }