using System; using System.Collections; using System.Collections.Generic; using System.Linq; using BlueWater.Npcs.Customers; using BlueWater.Utility; using Sirenix.OdinInspector; using Spine.Unity; using UnityEngine; using UnityEngine.Rendering; namespace BlueWater.Uis { public class BillUi : MonoBehaviour { [SerializeField] private Bill _billPrefab; [SerializeField] private SkeletonGraphic _chain; [Title("계산서")] [SerializeField] private Vector3 _spawnPosition; [SerializeField] private Transform _spawnLocation; [SerializeField] private List _billInfos = new(5); private ObservableList> _customerBills = new(); private Coroutine _updateInstance; private WaitForSeconds _waitForSeconds = new(0.1f); private bool _isMovedChain; private bool _isActivating; private const string Move = "Move"; private void Start() { _customerBills.ItemAdded += UpdateBillInfo; _customerBills.ItemRemoved += UpdateBillInfo; EventManager.OnOrderedCocktail += OrderedCocktail; EventManager.OnOrderResult += OrderResult; } private void OnDestroy() { _customerBills.ItemAdded -= UpdateBillInfo; _customerBills.ItemRemoved -= UpdateBillInfo; EventManager.OnOrderedCocktail -= OrderedCocktail; EventManager.OnOrderResult -= OrderResult; } private void OrderedCocktail(Customer customer) { var instance = Instantiate(_billPrefab, _spawnLocation); var newKeyValuePair = new KeyValuePair(customer, instance); _customerBills.Add(newKeyValuePair); instance.Initialize(customer, _spawnPosition, _billInfos[0].Position, () => _customerBills.Remove(newKeyValuePair)); customer.SetCurrentBill(instance); } private void OrderResult(Customer customer, bool isCorrected) { var keyValue = _customerBills.FirstOrDefault((element) => element.Key == customer); keyValue.Value.OrderResult(isCorrected); } private void UpdateBillInfo(ObservableList> sender, ListChangedEventArgs> e) { Utils.StartUniqueCoroutine(this, ref _updateInstance, UpdateBillInfoAfterDelay(sender)); } private IEnumerator UpdateBillInfoAfterDelay(ObservableList> sender) { yield return _waitForSeconds; foreach (var element in sender) { for (var i = 0; i < _billInfos.Count; i++) { if (element.Value.CurrentBillInfo == _billInfos[i]) break; if (_billInfos[i].IsEmpty) { PlayChainAnimation(); element.Value?.Move(_billInfos[i]); break; } } } StopChainAnimation(); _updateInstance = null; } private void PlayChainAnimation() { _chain.AnimationState.SetAnimation(0, Move, true); _isMovedChain = true; } private void StopChainAnimation() { if (!_isMovedChain || _isActivating) return; StartCoroutine(nameof(StopChainAnimationCoroutine)); } private IEnumerator StopChainAnimationCoroutine() { _isActivating = true; while (true) { var isMoving = false; foreach (var element in _billInfos) { if (!element.IsMoving) continue; isMoving = true; } if (!isMoving) { break; } yield return null; } _chain.AnimationState.ClearTrack(0); _isMovedChain = false; _isActivating = false; } } }