using System.Collections; using System.Collections.Generic; using System.Linq; using BlueWater.Npcs.Customers; using BlueWater.Utility; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater.Tycoons { public class CustomerManager : Singleton { [Title("손님 데이터")] [SerializeField, Required] private CustomerDataSo _customerDataSo; private Dictionary _customerDatas; [SerializeField, Required] private Customer _customerPrefab; [SerializeField, Required] private Transform _customerSpawnTransform; [Title("대기중인 손님 정보")] [SerializeField] private float _checkEmptySeatInterval = 0.5f; [SerializeField] private List _instanceCustomers = new(); [ShowInInspector] private Queue _waitingCustomers = new(); private CustomerTableController _customerTableController; private Coroutine _findEmptySeatCoroutineInstance; protected override void OnAwake() { _customerDatas = new Dictionary(_customerDataSo.CustomerDatas.Count); foreach (var element in _customerDataSo.CustomerDatas) { _customerDatas.TryAdd(element.Idx, element); } } private void Start() { _customerTableController = TycoonManager.Instance.CustomerTableController; } public void InstantiateCustomer() { var newCustomer = Instantiate(_customerPrefab, _customerSpawnTransform.position, Quaternion.identity); newCustomer.Initialize(); RegisterCustomer(newCustomer); } public void TryFindEmptySeat(Customer customer) { // 이미 대기열에 사람들이 있는 경우, 새로운 손님도 바로 대기열에 넣는다. if (_waitingCustomers.Count > 0) { _waitingCustomers.Enqueue(customer); return; } // 대기열에는 아무도 없는 경우 var emptySeat = _customerTableController.FindEmptySeat(); if (emptySeat == null) { // 내가 첫 대기열 손님이 된다. _waitingCustomers.Enqueue(customer); Utils.StartUniqueCoroutine(this, ref _findEmptySeatCoroutineInstance, CheckEmptySeatCoroutine()); return; } customer.SetTableSeat(emptySeat); emptySeat.ReserveSeat(); customer.AIMovement.Move(emptySeat.SeatTransform.position); } private IEnumerator CheckEmptySeatCoroutine() { var checkEmptySeatInterval = new WaitForSeconds(_checkEmptySeatInterval); while (_waitingCustomers.Count > 0) { var emptySeat = _customerTableController.FindEmptySeat(); if (emptySeat != null) { var customer = _waitingCustomers.Dequeue(); customer.SetTableSeat(emptySeat); emptySeat.ReserveSeat(); customer.AIMovement.Move(emptySeat.SeatTransform.position); continue; } yield return checkEmptySeatInterval; } _findEmptySeatCoroutineInstance = null; } public void RegisterCustomer(Customer customer) { Utils.RegisterList(_instanceCustomers, customer); } public void UnregisterCustomer(Customer customer) { Utils.UnregisterList(_instanceCustomers, customer); } public CustomerData GetRandomCustomerData() { var customerDataCount = _customerDatas.Count; if (customerDataCount == 0) { Debug.LogError($"{_customerDatas}의 값이 비어있습니다."); return null; } var randomIndex = Random.Range(0, customerDataCount); return _customerDatas.ElementAt(randomIndex).Value; } public List GetCurrentCustomers() => _instanceCustomers; } }