134 lines
4.5 KiB
C#
134 lines
4.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using BlueWater.Npcs.Customers;
|
|
using BlueWater.Utility;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEngine;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace BlueWater.Tycoons
|
|
{
|
|
public class CustomerManager : Singleton<CustomerManager>
|
|
{
|
|
[Title("손님 데이터")]
|
|
[SerializeField, Required]
|
|
private CustomerDataSo _customerDataSo;
|
|
private Dictionary<string, CustomerData> _customerDatas;
|
|
|
|
[SerializeField, Required]
|
|
private Customer _customerPrefab;
|
|
|
|
[SerializeField, Required]
|
|
private Transform _customerSpawnTransform;
|
|
|
|
[Title("대기중인 손님 정보")]
|
|
[SerializeField]
|
|
private float _checkEmptySeatInterval = 0.5f;
|
|
|
|
[field: SerializeField]
|
|
public List<Customer> InstanceCustomers { get; private set; } = new();
|
|
|
|
[ShowInInspector]
|
|
private Queue<Customer> _waitingCustomers = new();
|
|
|
|
private CustomerTableController _customerTableController;
|
|
private Coroutine _findEmptySeatCoroutineInstance;
|
|
|
|
public Action<Customer> OnInstantiateCustomer;
|
|
|
|
protected override void OnAwake()
|
|
{
|
|
_customerDatas = new Dictionary<string, CustomerData>(_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);
|
|
OnInstantiateCustomer?.Invoke(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<Customer> GetCurrentCustomers() => InstanceCustomers;
|
|
}
|
|
} |