using System.Collections; using System.Collections.Generic; using BlueWater.Npcs.Customers; using BlueWater.Utility; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater { public class CustomerManager : MonoBehaviour { [Title("손님 데이터")] [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 CustomerTableManager _customerTableManager; private Coroutine _findEmptySeatCoroutineInstance; private void Start() { _customerTableManager = RestaurantManager.Instance.CustomerTableManager; } 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 = _customerTableManager.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 = _customerTableManager.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); } } }