using System; using System.Collections; using System.Collections.Generic; using BlueWater.Audios; using BlueWater.Npcs.Customers; using BlueWater.Tycoons; using BlueWater.Utility; using UnityEngine; using Sirenix.OdinInspector; using TMPro; using UnityEngine.InputSystem; using UnityEngine.Serialization; using UnityEngine.UI; namespace BlueWater.Uis { public class TycoonResultUi : PausePopupUi { [Title("결과 카드")] [SerializeField] private TycoonResultCard _cardObject; [SerializeField] private Transform _cardLocation; [Title("컴포넌트")] [SerializeField] private GameObject _panel; [Title("타이틀")] [SerializeField] private GameObject _titlePanel; [Title("카드")] [SerializeField] private GameObject _cardTitlePanel; [SerializeField] private GameObject _resultCardPanel; [SerializeField] private GameObject _resultCardContents; [Title("라운드")] [SerializeField] private GameObject _roundPanel; [SerializeField] private TMP_Text _roundText; [Title("플레이 타임")] [SerializeField] private GameObject _playTimePanel; [SerializeField] private TMP_Text _playTimeText; [Title("텍스트 패널")] [SerializeField] private GameObject _textPanel; [Title("손님")] [SerializeField] private GameObject _customerPanel; [SerializeField] private GameObject _customerContents; [SerializeField] private GameObject _bigCatPanel; [SerializeField] private TMP_Text _bigCatText; private int _bigCatCount; [SerializeField] private GameObject _casperPanel; [SerializeField] private TMP_Text _casperText; private int _casperCount; [SerializeField] private GameObject _casperBlackPanel; [SerializeField] private TMP_Text _casperBlackText; private int _casperBlackCount; [SerializeField] private GameObject _catPanel; [SerializeField] private TMP_Text _catText; private int _catCount; [SerializeField] private GameObject _pumpkinPanel; [SerializeField] private TMP_Text _pumpkinText; private int _pumpkinCount; [SerializeField] private GameObject _reaperPanel; [SerializeField] private TMP_Text _reaperText; private int _reaperCount; [SerializeField] private GameObject _witchPanel; [SerializeField] private TMP_Text _witchText; private int _witchCount; [Title("서비스")] [SerializeField] private GameObject _serviceTitlePanel; [SerializeField] private GameObject _serviceContents; [Title("Good 서빙")] [SerializeField] private GameObject _goodServingPanel; [SerializeField] private TMP_Text _goodServingText; private int _goodServingCount; [Title("Fail 서빙")] [SerializeField] private GameObject _failServingPanel; [SerializeField] private TMP_Text _failedServingText; private int _failedServingCount; [Title("Miss 서빙")] [SerializeField] private GameObject _missServingPanel; [SerializeField] private TMP_Text _missServingText; private int _missServingCount; [Title("Good 청소")] [SerializeField] private GameObject _goodCleaningPanel; [SerializeField] private TMP_Text _goodCleaningText; private int _goodCleaningCount; [Title("Fail 청소")] [SerializeField] private GameObject _failedCleaningPanel; [SerializeField] private TMP_Text _failedCleaningText; private int _failedCleaningCount; [Title("골드")] [SerializeField] private GameObject _goldPanel; [SerializeField] private GameObject _goldTitlePanel; [SerializeField] private GameObject _goldContents; [Title("획득한 골드")] [SerializeField] private GameObject _goldGainedPanel; [SerializeField] private TMP_Text _goldGainedText; private int _goldGained; [SerializeField] private GameObject _plusObject; [Title("획득한 팁")] [SerializeField] private GameObject _tipGainedPanel; [SerializeField] private TMP_Text _tipGainedText; private int _tipGained; [SerializeField] private GameObject _minusObject; [Title("사용한 골드")] [SerializeField] private GameObject _goldSpentPanel; [SerializeField] private TMP_Text _goldSpentText; public int _goldSpent; [Title("총 획득 골드")] [SerializeField] private GameObject _totalGoldPanel; [SerializeField] private TMP_Text _totalGoldText; [SerializeField] private TMP_Text _minusPercentText; [Title("버튼")] [SerializeField] private Button _nextButton; [Title("연출 효과")] [SerializeField] private float _panelWaitingTime = 0.3f; [SerializeField] private float _totalGoldDuration = 1f; [Title("사운드")] private string _bgmName = "TycoonResult"; private Coroutine _showResultInstance; private InputAction _pressAnyKeyAction; public float _playTime; private bool _isSetData; [Title("[다음]랭킹")] [SerializeField] private RankUi _rankUi; private FirebaseManager _firebaseManager; private void Awake() { EventManager.OnShowResult += Open; EventManager.OnCheckedSkin += AddCustomerCount; EventManager.OnSucceedServing += AddServingCount; EventManager.OnMissedServing += AddMissedServingCount; EventManager.OnCleaningResult += AddCleaningCount; EventManager.OnAddedGold += AddGoldCount; } public void Start() { _pressAnyKeyAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.PressAnyKey); foreach (Transform element in _resultCardContents.transform) { Destroy(element.gameObject); } _firebaseManager = FirebaseManager.Instance.GetFirebaseManger(); _firebaseManager.resultUi = this; _nextButton.onClick.AddListener(() => _rankUi.RunRank()); _bigCatCount = 0; _casperCount = 0; _casperBlackCount = 0; _catCount = 0; _pumpkinCount = 0; _reaperCount = 0; _witchCount = 0; _goodServingCount = 0; _failedServingCount = 0; _missServingCount = 0; _goodCleaningCount = 0; _failedServingCount = 0; SetActiveUi(false); } public void Update() { _playTime += Time.deltaTime; //플레이타임 측정 (일시정지나 메뉴얼보는 시간은 제외) } private void OnDestroy() { EventManager.OnShowResult -= Open; EventManager.OnCheckedSkin -= AddCustomerCount; EventManager.OnSucceedServing -= AddServingCount; EventManager.OnMissedServing -= AddMissedServingCount; EventManager.OnCleaningResult -= AddCleaningCount; EventManager.OnAddedGold -= AddGoldCount; if (SceneController.Instance) { _nextButton?.onClick.RemoveListener(() => _rankUi.RunRank()); } _pressAnyKeyAction.performed -= OnShowImmediately; } [Button("결과 연출 테스트")] public override void Open() { OpenSwitch(InputActionMaps.TycoonUi); AudioManager.Instance.StopSfx("TycoonGameOver"); AudioManager.Instance.PlayBgm(_bgmName); Utils.StartUniqueCoroutine(this, ref _showResultInstance, ShowResultCoroutine()); } public override void Close() { } public override void EnableInput() { _pressAnyKeyAction.performed += OnShowImmediately; } public override void DisableInput() { _pressAnyKeyAction.performed -= OnShowImmediately; } private void OnShowImmediately(InputAction.CallbackContext context) { _pressAnyKeyAction.performed -= OnShowImmediately; ShowImmediately(); } private IEnumerator ShowResultCoroutine() { SetResultData(); WaitForSecondsRealtime panelWaitingTime = new WaitForSecondsRealtime(_panelWaitingTime); _panel.SetActive(true); _titlePanel.SetActive(true); yield return panelWaitingTime; _cardTitlePanel.SetActive(true); _resultCardPanel.SetActive(true); yield return panelWaitingTime; _resultCardContents.SetActive(true); yield return panelWaitingTime; _roundPanel.SetActive(true); _playTimePanel.SetActive(true); yield return panelWaitingTime; _textPanel.SetActive(true); _customerPanel.SetActive(true); _customerContents.SetActive(true); _bigCatPanel.SetActive(true); _casperPanel.SetActive(true); _casperBlackPanel.SetActive(true); _catPanel.SetActive(true); _pumpkinPanel.SetActive(true); _reaperPanel.SetActive(true); _witchPanel.SetActive(true); yield return panelWaitingTime; _serviceTitlePanel.SetActive(true); _serviceContents.SetActive(true); _goodServingPanel.SetActive(true); _failServingPanel.SetActive(true); _missServingPanel.SetActive(true); _goodCleaningPanel.SetActive(true); _failedCleaningPanel.SetActive(true); yield return panelWaitingTime; _goldPanel.SetActive(true); _goldTitlePanel.SetActive(true); _goldContents.SetActive(true); _goldGainedPanel.SetActive(true); _plusObject.SetActive(true); _tipGainedPanel.SetActive(true); _minusObject.SetActive(true); _goldSpentPanel.SetActive(true); yield return panelWaitingTime; float elapsedTime = 0f; int currentGold = TycoonManager.Instance.TycoonStatus.CurrentGold; int targetGold = ES3.Load(SaveData.EndGold, 0); string totalGoldLocalized = Utils.GetLocalizedString("TotalGold"); _totalGoldText.text = $"{totalGoldLocalized} : {currentGold:N0}"; _totalGoldPanel.SetActive(true); yield return panelWaitingTime; _minusPercentText.enabled = true; yield return panelWaitingTime; while (elapsedTime <= _totalGoldDuration) { var newGold = (int)Mathf.Lerp(currentGold, targetGold, elapsedTime / _totalGoldDuration); _totalGoldText.text = $"{totalGoldLocalized} : {newGold:N0}"; elapsedTime += Time.unscaledDeltaTime; yield return null; } _totalGoldText.text = $"{totalGoldLocalized} : {targetGold:N0}"; yield return panelWaitingTime; _nextButton.gameObject.SetActive(true); _pressAnyKeyAction.performed -= OnShowImmediately; yield return null; } private void SetActiveUi(bool isActive) { _panel.SetActive(isActive); _titlePanel.SetActive(isActive); _cardTitlePanel.SetActive(isActive); _resultCardPanel.SetActive(isActive); _resultCardContents.SetActive(isActive); _roundPanel.SetActive(isActive); _playTimePanel.SetActive(isActive); _textPanel.SetActive(isActive); _customerPanel.SetActive(isActive); _customerContents.SetActive(isActive); _bigCatPanel.SetActive(isActive); _casperPanel.SetActive(isActive); _casperBlackPanel.SetActive(isActive); _catPanel.SetActive(isActive); _pumpkinPanel.SetActive(isActive); _reaperPanel.SetActive(isActive); _witchPanel.SetActive(isActive); _serviceTitlePanel.SetActive(isActive); _serviceContents.SetActive(isActive); _goodServingPanel.SetActive(isActive); _failServingPanel.SetActive(isActive); _missServingPanel.SetActive(isActive); _goodCleaningPanel.SetActive(isActive); _failedCleaningPanel.SetActive(isActive); _goldPanel.SetActive(isActive); _goldTitlePanel.SetActive(isActive); _goldContents.SetActive(isActive); _goldGainedPanel.SetActive(isActive); _plusObject.SetActive(isActive); _tipGainedPanel.SetActive(isActive); _minusObject.SetActive(isActive); _goldSpentPanel.SetActive(isActive); _totalGoldPanel.SetActive(isActive); _minusPercentText.enabled = isActive; _nextButton.gameObject.SetActive(isActive); } private void SetResultData() { int currentGold = TycoonManager.Instance.TycoonStatus.CurrentGold; float endGoldMultiplier = -0.5f + TycoonManager.Instance.TycoonStatus.EndGoldMultiplier; int addedGold = Mathf.RoundToInt(currentGold * endGoldMultiplier); int saveGold = currentGold + addedGold; ES3.Save(SaveData.EndGold, saveGold); ES3.Save(SaveData.CompleteFirstGame, true); int tries = ES3.Load(SaveData.Tries, 0); ES3.Save(SaveData.Tries, ++tries); Dictionary selectedCards = TycoonManager.Instance.TycoonCardController.SelectedCard; foreach (var element in selectedCards) { TycoonResultCard newCard = Instantiate(_cardObject, _cardLocation); newCard.SetImage(TycoonManager.Instance.TycoonCardController.CardDataSo.GetDataByIdx(element.Key).Sprite); newCard.SetText(TycoonManager.Instance.TycoonCardController.CardDataSo.GetDataByIdx(element.Key).ScriptText); newCard.SetCount(element.Value); newCard.name = element.Key; } _roundText.text = $"{Utils.GetLocalizedString("Round")} : {TycoonManager.Instance.GetCurrentLevelData().Idx}"; _playTimeText.text = $"{Utils.GetLocalizedString("PlayTime")} : {Mathf.FloorToInt(_playTime / 60f):D2} : {Mathf.FloorToInt(_playTime % 60f):D2}"; _bigCatText.text = _bigCatCount.ToString(); _casperText.text = _casperCount.ToString(); _casperBlackText.text = _casperBlackCount.ToString(); _catText.text = _catCount.ToString(); _pumpkinText.text = _pumpkinCount.ToString(); _reaperText.text = _reaperCount.ToString(); _witchText.text = _witchCount.ToString(); _goodServingText.text = _goodServingCount.ToString(); _failedServingText.text = _failedServingCount.ToString(); _missServingText.text = _missServingCount.ToString(); _goodCleaningText.text = _goodCleaningCount.ToString(); _failedCleaningText.text = _failedCleaningCount.ToString(); _goldGainedText.text = _goldGained.ToString("N0"); _tipGainedText.text = _tipGained.ToString("N0"); _goldSpentText.text = _goldSpent.ToString("N0"); _totalGoldText.text = $"{Utils.GetLocalizedString("TotalGold")} : {ES3.Load(SaveData.EndGold, 0):N0}"; int percent = Mathf.RoundToInt(endGoldMultiplier * 100); char sign = percent >= 0 ? '+' : '-'; _minusPercentText.color = percent >= 0 ? Color.blue : Color.red; _minusPercentText.text = $"{sign} {Mathf.Abs(percent)}%"; _isSetData = true; } [Button("결과 즉시 테스트")] private void ShowImmediately() { if (_showResultInstance != null) { StopCoroutine(_showResultInstance); _showResultInstance = null; } if (!_isSetData) { SetResultData(); } SetActiveUi(true); } private void AddCustomerCount(CustomerSkin skinIndex) { switch (skinIndex) { case CustomerSkin.BigCat: _bigCatCount++; break; case CustomerSkin.Casper: _casperCount++; break; case CustomerSkin.CasperBlack: _casperBlackCount++; break; case CustomerSkin.Cat: _catCount++; break; case CustomerSkin.PumkinHead: _pumpkinCount++; break; case CustomerSkin.Reaper: _reaperCount++; break; case CustomerSkin.Witch: _witchCount++; break; default: throw new Exception("손님 스킨 인덱스 오류"); } } private void AddServingCount(bool orderedCorrected) { if (orderedCorrected) { _goodServingCount++; } else { _failedServingCount++; } } private void AddMissedServingCount() => _missServingCount++; private void AddCleaningCount(bool isSucceed) { if (isSucceed) { _goodCleaningCount++; } else { _failedCleaningCount++; } } private void AddGoldCount(int addedGold, bool isTip) { if (addedGold < 0) { _goldSpent += Mathf.Abs(addedGold); return; } if (isTip) { _tipGained += addedGold; } else { _goldGained += addedGold; } } } }