using System; using System.Collections; using BlueWater.Npcs.Customers; using DG.Tweening; using TMPro; using UnityEngine; using UnityEngine.UI; using Random = UnityEngine.Random; namespace BlueWater { public class Bill : MonoBehaviour { [SerializeField] private RectTransform _rect; [SerializeField] private AnimationController _animationController; [SerializeField] private Slider _slider; [SerializeField] private Image _filledImage; [SerializeField] private Image _orderImage; [SerializeField] private GameObject _makingCocktailPivotObject; [SerializeField] private GameObject _checkImageObject; [SerializeField] private GameObject _stampImageObject; [SerializeField] private GameObject _tableNumberImageObject; [SerializeField] private TMP_Text _tableNumberText; [SerializeField] private Color _startColor = Color.green; [SerializeField] private Color _endColor = Color.red; public BillInfo CurrentBillInfo { get; private set; } private Tween _sliderTween; private Vector3 _spawnPosition; private float _maxDistance; public void Initialize(Customer customer, Vector3 spawnPosition, Vector3 billInfoPosition0) { _slider.onValueChanged.AddListener(OnSliderValueChanged); _spawnPosition = spawnPosition; _rect.anchoredPosition = _spawnPosition; _maxDistance = Vector3.Distance(_rect.anchoredPosition, billInfoPosition0); _slider.value = 1f; _slider.gameObject.SetActive(true); _orderImage.sprite = customer.OrderedCocktailData.Sprite; _orderImage.gameObject.SetActive(true); _makingCocktailPivotObject.SetActive(false); _checkImageObject.SetActive(false); _stampImageObject.SetActive(false); _tableNumberText.text = customer.CurrentTableSeat.TableNumber.ToString(); _tableNumberImageObject.SetActive(true); SetTween(customer.CurrentLevelData.WaitTime, customer.CurrentLevelData.HurryTime); } public void SetTween(int waitTime, int hurryTime) { _sliderTween?.Kill(); _sliderTween = _slider.DOValue(0f, hurryTime) .From(1f) .SetEase(Ease.Linear) .SetDelay(waitTime) .SetAutoKill(true); } private void OnDestroy() { _slider.onValueChanged.RemoveListener(OnSliderValueChanged); DOTween.Kill(_rect); } private void OnSliderValueChanged(float value) { _filledImage.color = Color.Lerp(_endColor, _startColor, value); } public void Move(BillInfo billInfo) { if (!_rect) return; if (CurrentBillInfo != null) { CurrentBillInfo.IsEmpty = true; } CurrentBillInfo = billInfo; CurrentBillInfo.IsEmpty = false; CurrentBillInfo.IsMoving = true; var distance = Vector3.Distance(_rect.anchoredPosition, CurrentBillInfo.Position); var moveTime = Mathf.Lerp(0.2f, 1f, distance / _maxDistance); var rotationAngle = Mathf.Lerp(8f, 40f, distance / _maxDistance); var punchStrength = Mathf.Lerp(1f, 5f, distance / _maxDistance); var moveSequence = DOTween.Sequence().SetAutoKill(true); moveSequence.Append(_rect.DOLocalMoveX(CurrentBillInfo.Position.x, moveTime)); moveSequence.Join(_rect.DOLocalRotate(new Vector3(0, 0, rotationAngle), moveTime / 5f)); moveSequence.Join(_rect.DOPunchRotation(new Vector3(0f, 0f, punchStrength), moveTime * 4f / 5f, 3, 0.2f) .SetDelay(0.2f) .SetEase(Ease.InOutBounce)); moveSequence.AppendCallback(OnArrivedTarget); } private void OnArrivedTarget() { if (!_rect) return; CurrentBillInfo.IsMoving = false; var randomZ = Random.Range(-15f, 15f); var arrivedSequence = DOTween.Sequence(); arrivedSequence.Append(_rect.DOLocalRotate(Vector3.zero, 0.2f).SetEase(Ease.InQuad)); arrivedSequence.Append(_rect.DOPunchRotation(new Vector3(0f, 0f, -20f), 1f, 5, 0.5f) .SetEase(Ease.InOutBounce)); arrivedSequence.Append(_rect.DOLocalRotate(new Vector3(0f, 0f, randomZ), 0.2f).SetEase(Ease.InQuad)); } public void OrderResult(bool isSucceed, Action onDestroyAction) { StartCoroutine(WaitForAnimation(isSucceed, onDestroyAction)); } private IEnumerator WaitForAnimation(bool isSucceed, Action onDestroyAction) { _animationController.SetAnimationParameter("isOrderedSucceed", isSucceed); _animationController.SetAnimationParameter("isAnimationTrigger", true); var animationName = isSucceed ? "OrderedSucceed" : "OrderedFail"; var animationStarted = false; yield return StartCoroutine(_animationController.WaitForAnimationToRun(animationName, success => animationStarted = success)); if (!animationStarted) { Debug.LogError("애니메이션 오류"); } _stampImageObject.SetActive(true); _sliderTween.Kill(); var isTrigger = false; while (_animationController.IsComparingCurrentAnimation(animationName) && _animationController.GetCurrentAnimationNormalizedTime() < 1f) { if (!isTrigger && _animationController.GetCurrentAnimationNormalizedTime() >= 0.5f) { _slider.gameObject.SetActive(false); _makingCocktailPivotObject.SetActive(false); _checkImageObject.gameObject.SetActive(false); _orderImage.gameObject.SetActive(false); _stampImageObject.SetActive(false); _tableNumberImageObject.SetActive(false); isTrigger = true; } yield return null; } CurrentBillInfo.IsEmpty = true; onDestroyAction?.Invoke(); Destroy(gameObject); } public void BartenderMakingCocktail() { _makingCocktailPivotObject?.gameObject.SetActive(true); } public void BartenderCompleteMakingCocktail() { _makingCocktailPivotObject?.gameObject.SetActive(false); _checkImageObject?.gameObject.SetActive(true); _animationController?.SetAnimationParameter("isBartenderChecked", true); } public void ResetGauge() { if (_sliderTween == null) { Debug.LogError("게이지 리셋 오류"); return; } _sliderTween.Restart(); } } }