diff --git a/Assets/_DDD/_ScriptAssets/Prefabs/UiManager.prefab b/Assets/_DDD/_ScriptAssets/Prefabs/UiManager.prefab index b7d387cea..34d57f41b 100644 --- a/Assets/_DDD/_ScriptAssets/Prefabs/UiManager.prefab +++ b/Assets/_DDD/_ScriptAssets/Prefabs/UiManager.prefab @@ -3723,10 +3723,6 @@ PrefabInstance: propertyPath: m_AnchoredPosition.y value: 0 objectReference: {fileID: 0} - - target: {fileID: 5495376218471957137, guid: 1b0cdbed9c1b7d148b63ac3b70f9a28a, type: 3} - propertyPath: m_SizeDelta.y - value: 0 - objectReference: {fileID: 0} - target: {fileID: 5980190398288299945, guid: 1b0cdbed9c1b7d148b63ac3b70f9a28a, type: 3} propertyPath: m_AnchorMax.x value: 1 @@ -3833,7 +3829,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 8146336867650838388, guid: 1b0cdbed9c1b7d148b63ac3b70f9a28a, type: 3} propertyPath: m_AnchoredPosition.y - value: -15 + value: -96.38 objectReference: {fileID: 0} - target: {fileID: 8292253660733231715, guid: 1b0cdbed9c1b7d148b63ac3b70f9a28a, type: 3} propertyPath: m_AnchorMax.y diff --git a/Assets/_DDD/_ScriptAssets/So/GameFlowSceneMappingSo.asset b/Assets/_DDD/_ScriptAssets/So/GameFlowSceneMappingSo.asset index 04e738763..c83d53d9e 100644 --- a/Assets/_DDD/_ScriptAssets/So/GameFlowSceneMappingSo.asset +++ b/Assets/_DDD/_ScriptAssets/So/GameFlowSceneMappingSo.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07b472ddf1cb740a9b7f5b859e56608240c2137a0f8c82d3a287deedfcc8a6d7 +oid sha256:2243e7e7a0b06f8b670339801d22deec1f5f79699d57959d63d071f0e4e9c4d3 size 3666 diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/Npc/Customer/CustomerCharacter.cs b/Assets/_DDD/_Scripts/Restaurant/Character/Npc/Customer/CustomerCharacter.cs index 24c04c2e0..20968c093 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/Npc/Customer/CustomerCharacter.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/Npc/Customer/CustomerCharacter.cs @@ -1,7 +1,4 @@ -using System.Threading.Tasks; -using Opsive.BehaviorDesigner.Runtime; using UnityEngine; -using UnityEngine.AddressableAssets; namespace DDD.Restaurant { @@ -16,6 +13,14 @@ protected override void Awake() base.Awake(); _customerAi = GetComponent(); } + + private void OnDestroy() + { + if (RestaurantState.Instance?.RunState != null) + { + RestaurantState.Instance.RunState.RemoveCustomer(gameObject); + } + } public void Initialize(CustomerDataEntry customerDataEntry) { diff --git a/Assets/_DDD/_Scripts/Restaurant/Controller/Conrtollers/Run/Customer/CustomerFactory.cs b/Assets/_DDD/_Scripts/Restaurant/Controller/Conrtollers/Run/Customer/CustomerFactory.cs index fadd08e19..366cde340 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Controller/Conrtollers/Run/Customer/CustomerFactory.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Controller/Conrtollers/Run/Customer/CustomerFactory.cs @@ -43,6 +43,8 @@ public async Task CreateAsync(CustomerSpawnArgs args) { initializer.Initialize(args.CustomerDataEntry); } + RestaurantState.Instance.RunState.AddCustomer(newCustomer); + return newCustomer; } diff --git a/Assets/_DDD/_Scripts/Restaurant/Controller/Conrtollers/RunController.cs b/Assets/_DDD/_Scripts/Restaurant/Controller/Conrtollers/RunController.cs index 149a92d3e..5784e7f6b 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Controller/Conrtollers/RunController.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Controller/Conrtollers/RunController.cs @@ -116,8 +116,12 @@ SpawnSchedule MakeSchedule() => scheduleBuilder.Build(new SpawnScheduleBuildArgs { break; } - - if (_spawnSchedule.TryDequeue(out var customerId) == false) break; + + if (_spawnSchedule.TryDequeue(out var customerId) == false) + { + _restaurantRunStateSo.SetSpawnCompleted(true); + break; + } if (_customerDataAsset.TryGetDataById(customerId, out var customerData)) { @@ -134,6 +138,14 @@ await _iCustomerFactory.CreateAsync(new CustomerSpawnArgs await Awaitable.WaitForSecondsAsync(wait, token); } + + if (_restaurantRunStateSo.GetSpawnCompleted() && token.IsCancellationRequested == false) + { + await WaitForAllCustomersToLeave(token); + + // 모든 손님이 떠났으면 다음 flow로 전환 + await TransitionToNextFlow(); + } } private static ISpawnScheduleBuilder CreateBuilder(SpawnType type) @@ -145,5 +157,28 @@ private static ISpawnScheduleBuilder CreateBuilder(SpawnType type) _ => new RandomSpawnScheduleBuilder() }; } + + private async Task WaitForAllCustomersToLeave(CancellationToken token) + { + const float checkInterval = 1f; // 1초마다 체크 + + while (!token.IsCancellationRequested && Application.isPlaying) + { + if (_restaurantRunStateSo.AllCustomersGone()) + { + Debug.Log("[RunController] 모든 손님이 떠났습니다."); + break; + } + + await Awaitable.WaitForSecondsAsync(checkInterval, token); + } + } + + private async Task TransitionToNextFlow() + { + _restaurantRunStateSo.ClearCustomers(); + + await GameFlowManager.Instance.ChangeFlow(GameFlowState.SettlementRestaurant); + } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantRunState.cs b/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantRunState.cs index e0dafce35..2dc3b8574 100644 --- a/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantRunState.cs +++ b/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantRunState.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using UnityEngine; namespace DDD @@ -6,10 +7,46 @@ public class RestaurantRunState : ScriptableObject { private Vector3 _spawnPoint = new(5f, 0f, 4f); public Vector3 SpawnPoint => _spawnPoint; + + private List _activeCustomers = new(); + private bool _spawnCompleted; public void InitializeSpawnPoint(Vector3 spawnPoint) { _spawnPoint = spawnPoint; } + + public void AddCustomer(GameObject customer) + { + if (_activeCustomers.Contains(customer) == false) + { + _activeCustomers.Add(customer); + } + } + + public void RemoveCustomer(GameObject customer) + { + _activeCustomers.Remove(customer); + } + + public void SetSpawnCompleted(bool completed) + { + _spawnCompleted = completed; + } + + public bool AllCustomersGone() + { + // null 체크 후 실제로 활성화된 손님이 없는지 확인 + _activeCustomers.RemoveAll(customer => customer == null); + return _activeCustomers.Count == 0; + } + + public void ClearCustomers() + { + _activeCustomers.Clear(); + _spawnCompleted = false; + } + + public bool GetSpawnCompleted() => _spawnCompleted; } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantSettlementState.cs b/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantSettlementState.cs index 33e689f04..78cb52ce6 100644 --- a/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantSettlementState.cs +++ b/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantSettlementState.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using UnityEngine; namespace DDD.Restaurant @@ -31,12 +32,26 @@ public void CustomerSettlement(CustomerType customerType, int price, string cook TotalRevenue += price; - SoldCookingCounts.TryAdd(cookingId, 1); + if (SoldCookingCounts.TryAdd(cookingId, 1) == false) + { + SoldCookingCounts[cookingId]++; + } } public void SaveSettlementResult() { // TODO : 골드 경험치 등 필요 데이터 저장 } + + public void CompleteSettlement() + { + GameState.Instance.LevelState.IncreaseLevel(); + //_ = ChangeFlow(); + } + + // private async Task ChangeFlow() + // { + // + // } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantSettlementUi/SettlementUi.cs b/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantSettlementUi/SettlementUi.cs index e495425a9..f55ce6687 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantSettlementUi/SettlementUi.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantSettlementUi/SettlementUi.cs @@ -21,6 +21,9 @@ protected override GameObject GetInitialSelected() protected override void OnCreatedInitializePopup() { + _viewModel.OnCompletedSettlement += HandleCompleteSettlement; + _confirmButton.AddListener(HandleCompleteSettlement); + BindingHelper.BindText(_bindingContext, _totalRevenueLabel, nameof(_viewModel.TotalRevenue)); BindingHelper.BindText(_bindingContext, _normalCustomersLabel, nameof(_viewModel.NormalCustomers)); BindingHelper.BindText(_bindingContext, _specialCustomersLabel, nameof(_viewModel.SpecialCustomers)); @@ -62,5 +65,11 @@ private void HandleInteract1() var interactable = selected?.GetComponent(); interactable?.OnInteract(); } + + private void HandleCompleteSettlement() + { + Close(); + _viewModel.SettlementState.CompleteSettlement(); + } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantSettlementUi/SettlementViewModel.cs b/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantSettlementUi/SettlementViewModel.cs index d160e3612..534a22178 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantSettlementUi/SettlementViewModel.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantSettlementUi/SettlementViewModel.cs @@ -1,3 +1,4 @@ +using System; using TMPro; using UnityEngine; @@ -5,8 +6,8 @@ namespace DDD.Restaurant { public class SettlementViewModel : SimpleViewModel { - private RestaurantSettlementData _settlementData; - private RestaurantSettlementState _settlementState; + public RestaurantSettlementData SettlementData; + public RestaurantSettlementState SettlementState; private string _totalRevenue; public string TotalRevenue @@ -29,10 +30,12 @@ public string SpecialCustomers private set => SetField(ref _specialCustomers, value); } + public Action OnCompletedSettlement; + public override void Initialize() { - _settlementData = RestaurantData.Instance.SettlementData; - _settlementState = RestaurantState.Instance.SettlementState; + SettlementData = RestaurantData.Instance.SettlementData; + SettlementState = RestaurantState.Instance.SettlementState; } public override void Cleanup() @@ -42,16 +45,16 @@ public override void Cleanup() public void UpdateSettlement(Transform parent) { - TotalRevenue = $"총 수익 : {_settlementState.TotalRevenue.ToGold()}"; - NormalCustomers = $"일반 손님 수 : {_settlementState.NormalCustomers}"; - SpecialCustomers = $"스폐셜 손님 수 : {_settlementState.SpecialCustomers}"; + TotalRevenue = $"총 수익 : {SettlementState.TotalRevenue.ToGold()}"; + NormalCustomers = $"일반 손님 수 : {SettlementState.NormalCustomers}"; + SpecialCustomers = $"스폐셜 손님 수 : {SettlementState.SpecialCustomers}"; Utils.DestroyAllChildren(parent); int count = 0; - foreach (var soldCookingCount in _settlementState.SoldCookingCounts) + foreach (var soldCookingCount in SettlementState.SoldCookingCounts) { count++; - var instance = Instantiate(_settlementData.TextPrefab, parent); + var instance = Instantiate(SettlementData.TextPrefab, parent); var textMeshProUGUI = instance.GetComponent(); var cookingName = LocalizationManager.Instance.GetName(soldCookingCount.Key); textMeshProUGUI.text = $"판매된 메뉴{count} : {cookingName} {soldCookingCount.Value}";