using System.Collections; using System.Collections.Generic; using BlueWater.Audios; using BlueWater.Tycoons; using BlueWater.Utility; using DG.Tweening; using Sirenix.OdinInspector; using TMPro; using UnityEngine; using UnityEngine.UI; namespace BlueWater.Uis { public class ExpUi : MonoBehaviour { [SerializeField, Required] private TMP_Text _levelText; [SerializeField] private Slider _expSlider; [SerializeField] private Image _filledImage; [SerializeField] private float _animationTime = 0.2f; [SerializeField] private string _levelUpSfxName = "LevelUp"; [Title("레벨 텍스트")] [SerializeField] private Vector3 _punchScale = new(1.5f, 1.5f, 1.5f); [SerializeField] private float _duration = 1f; private Queue _expQueue = new(); private Coroutine _changeExpInstance; private Color _originalColor; private Tween _expSliderTween; private Tween _levelTextTween; private bool _isAnimating; private void Awake() { EventManager.OnChangeExp += ChangeExp; EventManager.OnLevelUp += ChangeLevel; if (_expSlider) { _expSlider.value = 0f; } _originalColor = _filledImage.color; _expSliderTween = _filledImage.DOColor(Color.white, 0.25f) .SetAutoKill(false) .Pause() .OnComplete(() => { _filledImage.DOColor(_originalColor, 0.25f); }); _levelTextTween = _levelText.transform.DOPunchScale(_punchScale, _duration, 1) .SetAutoKill(false) .Pause(); } private void OnDestroy() { EventManager.OnChangeExp -= ChangeExp; EventManager.OnLevelUp += ChangeLevel; _expSliderTween.Kill(); _levelTextTween.Kill(); } private void ChangeLevel(LevelData levelData) { _levelText.text = $"Round.{levelData.Idx}"; if (levelData.Idx != "1") { _levelTextTween.Restart(); } } private void ChangeExp(int addedExp) { _expQueue.Enqueue(addedExp); if (!_isAnimating) { Utils.StartUniqueCoroutine(this, ref _changeExpInstance, AnimateExpChange()); } } private IEnumerator AnimateExpChange() { _isAnimating = true; while (_expQueue.Count > 0) { var currentLevelData = TycoonManager.Instance.GetCurrentLevelData(); var startExp = TycoonManager.Instance.TycoonStatus.CurrentExp; var addedExp = _expQueue.Dequeue(); var requireExp = currentLevelData.RequiredExp; var endExp = startExp + addedExp; var remainExp = endExp - requireExp; var elapsedTime = 0f; while (true) { var newExp = Mathf.Lerp(startExp, endExp, elapsedTime / _animationTime); TycoonManager.Instance.TycoonStatus.CurrentExp = (int)newExp; var expClamp = Mathf.Clamp01(newExp / requireExp); if (_expSlider) { _expSlider.value = expClamp; } if (newExp >= requireExp) { _expSliderTween.Restart(); yield return _expSliderTween.WaitForCompletion(); TycoonManager.Instance.TycoonStatus.CurrentLevel++; AudioManager.Instance.PlaySfx(_levelUpSfxName); currentLevelData = TycoonManager.Instance.GetCurrentLevelData(); requireExp = currentLevelData.RequiredExp; if (_expSlider) { _expSlider.value = 0f; } newExp = 0; TycoonManager.Instance.TycoonStatus.CurrentExp = (int)newExp; startExp = 0; endExp = remainExp; remainExp = endExp - requireExp; elapsedTime = 0f; } else { elapsedTime += Time.deltaTime; } if (newExp >= endExp) break; yield return null; } } _isAnimating = false; _changeExpInstance = null; } [Button("경험치 증가 테스트")] private void Test(int exp) { EventManager.InvokeChangeExp(exp); } } }