// using System; // using System.Collections; // using System.Collections.Generic; // using System.Linq; // using DDD.Audios; // using DDD.Items; // using DDD.Players.Tycoons; // using DDD.Tycoons; // using DDD.Utility; // using Sirenix.OdinInspector; // using TMPro; // using UnityEngine; // using UnityEngine.Pool; // using UnityEngine.UI; // // namespace DDD // { // public class LiquidController : MonoBehaviour // { // #region Variables // // [Title("컴포넌트")] // [SerializeField] // private GameObject _liquidPanel; // // [SerializeField] // private GameObject _shaker; // // [SerializeField] // private Renderer _renderTexture; // // [SerializeField] // private Renderer _liquidRenderer; // // [SerializeField] // private Collider2D _reachedCollider; // // [SerializeField] // private TMP_Text _amountText; // // [SerializeField] // private Image _balloonImage; // // [SerializeField] // private Image _completeCocktailImage; // // [SerializeField] // private TMP_Text _completeText; // // [Title("스폰 데이터")] // [SerializeField, Required] // private Transform _spawnTransform; // // [SerializeField] // private Transform _spawnLocation; // // [SerializeField] // private Vector3 _pushDirection = new(-3f, -1f, 0f); // // [SerializeField] // private float _pushPower = 50; // // [Title("사운드")] // [SerializeField] // private string _pouringSfxName = "Pouring"; // // [SerializeField] // private string _succeedMakingCocktailSfxName = "SucceedMakingCocktail"; // // [SerializeField] // private string _failedMakingCocktailSfxName = "FailedMakingCocktail"; // // [Title("Liquid / Garnish")] // [SerializeField, Required, Tooltip("원액 프리팹")] // private Liquid _liquidObject; // // [SerializeField, Required, Tooltip("가니쉬 프리팹")] // private Garnish _garnishObject; // // [SerializeField, Tooltip("초당 생성되는 액체 수(ml)")] // private int _liquidsPerSecond = 100; // // [SerializeField, Range(0f, 1f), Tooltip("목표 색상으로 변경되는데 걸리는 시간")] // private float _colorLerpSpeed = 0.5f; // // [SerializeField, Range(1f, 5f), Tooltip("목표 색상 * 밝기")] // private float _colorIntensity = 2f; // // [Title("도착 지점")] // [SerializeField, Tooltip("도착 지점의 Lerp값")] // private Vector2 _reachedLerpPosition = new(-10.5f, 4f); // // [Title("오브젝트 풀링")] // [SerializeField, Tooltip("오브젝트 풀링 최대 개수")] // private int _objectPoolCount = 1000; // // [Title("패널")] // [SerializeField] // private Sprite _centerBalloonImage; // // [SerializeField] // private Sprite _playerBalloonImage; // // [SerializeField] // private float _moveToPlayerDuration = 0.2f; // // [SerializeField] // private float _moveToCenterDuration = 0.15f; // // [SerializeField] // private Vector3 _centerPosition = new(-300f, 0f, 0f); // // [SerializeField] // private Vector3 _endPositionOffset = new(0f, 20f, 0f); // // [SerializeField] // private Vector3 _endScale = new(0.3f, 0.3f, 0.3f); // // [SerializeField] // private Vector2 _cameraDistance = new(5f, 15f); // // [SerializeField] // private Vector2 _offsetY = new(20f, 15f); // // private Barrel _currentBarrel; // private IObjectPool _liquidObjectPool; // private IObjectPool _garnishObjectPool; // private List _activeLiquidDatas = new(); // private List _activeGarnishDatas = new(); // private Dictionary _liquidDataCounts = new(7); // private Material _instanceMaterial; // // private bool _isShowingPanel; // private bool _isPouring; // private bool _isCompleted; // private float _elapsedTime = float.PositiveInfinity; // private int _maxLiquidCount; // private int _instanceLiquidCount; // private float _currentLiquidAmount; // private float _liquidReachedTime; // private float _timeInterval; // private Color _currentMixedColor = Color.black; // private Color _targetColor; // private Camera _overlayCamera; // private TycoonPlayer _tycoonPlayer; // private Vector2 _originalReachedPosition; // private Vector3 _lastPlayerPosition; // private Vector3 _originalPanelScale; // private Coroutine _movePanelToPlayerInstance; // private Coroutine _movePanelToCenterInstance; // // // Hashes // private static readonly int LiquidAmountHash = Shader.PropertyToID("_LiquidAmount"); // private static readonly int LiquidColorHash = Shader.PropertyToID("_LiquidColor"); // // #endregion // // // Unity events // #region Unity events // // private void Awake() // { // _liquidObjectPool = new ObjectPool(CreateLiquidObject, OnGetLiquidObject, OnReleaseLiquidObject, OnDestroyLiquidObject, maxSize: _objectPoolCount); // _garnishObjectPool = new ObjectPool(CreateGarnishObject, OnGetGarnishObject, OnReleaseGarnishObject, OnDestroyGarnishObject, maxSize: _objectPoolCount); // } // // private void Start() // { // EventManager.OnCocktailDiscarded += ReleaseAllObject; // EventManager.OnPlaceOnServingTable += ReleaseAllObject; // EventManager.OnCocktailServedToCustomer += ReleaseAllObject; // EventManager.OnChangedRandomCocktail += ReleaseAllObject; // LiquidIngredient.OnReachedTarget += OnTargetReached; // Barrel.OnBarrelInteracted += HandleBarrelInteraction; // Barrel.OnBarrelCancelInteracted += HandleBarrelCancelInteraction; // // _overlayCamera = TycoonCameraManager.Instance.LiquidOverlayCamera; // _tycoonPlayer = GameManager.Instance.CurrentTycoonPlayer; // _instanceMaterial = Instantiate(_liquidRenderer.material); // _liquidRenderer.material = _instanceMaterial; // // _originalReachedPosition = _reachedCollider.transform.position; // _originalPanelScale = _liquidPanel.transform.localScale; // _instanceMaterial.SetFloat(LiquidAmountHash, 0f); // _timeInterval = 1f / _liquidsPerSecond; // _shaker.SetActive(true); // _amountText.enabled = true; // _completeCocktailImage.enabled = false; // _completeText.enabled = false; // _instanceLiquidCount = 0; // _maxLiquidCount = ItemManager.Instance.CocktailDataSo.MaxLiquidCount; // SetCurrentAmount(0f); // } // // private void FixedUpdate() // { // if (_isPouring) // { // var currentBarrel = _currentBarrel; // _elapsedTime += Time.deltaTime; // // while (_elapsedTime >= _timeInterval) // { // if (!currentBarrel.CanConsume(1)) // { // HandleBarrelCancelInteraction(); // return; // } // // switch (currentBarrel.GetLiquidData().Type) // { // case LiquidType.None: // Debug.LogError("원액 종류 None 오류"); // break; // case LiquidType.Liquid: // _liquidObjectPool.Get(); // break; // case LiquidType.Garnish: // _garnishObjectPool.Get(); // break; // default: // throw new ArgumentOutOfRangeException(); // } // // if (!_liquidDataCounts.TryAdd(currentBarrel.GetLiquidData(), 1)) // { // _liquidDataCounts[currentBarrel.GetLiquidData()] += 1; // } // // currentBarrel.Consume(1); // _elapsedTime -= _timeInterval; // // // 술이 완성되었을 때 // if (_instanceLiquidCount >= _maxLiquidCount) // { // StartCoroutine(nameof(CompleteCocktail)); // return; // } // } // } // // if (_liquidReachedTime + _colorLerpSpeed >= Time.time) // { // _currentMixedColor = Color.Lerp(_currentMixedColor, _targetColor, _colorLerpSpeed * Time.deltaTime); // _instanceMaterial.SetColor(LiquidColorHash, _currentMixedColor * _colorIntensity); // } // } // // private void OnDestroy() // { // EventManager.OnCocktailDiscarded -= ReleaseAllObject; // EventManager.OnPlaceOnServingTable -= ReleaseAllObject; // EventManager.OnCocktailServedToCustomer -= ReleaseAllObject; // EventManager.OnChangedRandomCocktail -= ReleaseAllObject; // LiquidIngredient.OnReachedTarget -= OnTargetReached; // Barrel.OnBarrelInteracted -= HandleBarrelInteraction; // Barrel.OnBarrelCancelInteracted -= HandleBarrelCancelInteraction; // } // // #endregion // // // Object pooling system // #region Object pooling system // // // 원액 오브젝트 풀 // private Liquid CreateLiquidObject() // { // var instance = Instantiate(_liquidObject, _spawnTransform.position, Quaternion.identity, _spawnLocation); // instance.SetManagedPool(_liquidObjectPool); // return instance; // } // // private void OnGetLiquidObject(Liquid liquid) // { // _instanceLiquidCount++; // liquid.Initialize(_spawnTransform.position, Quaternion.identity, _reachedCollider, _pushDirection.normalized * _pushPower, _currentBarrel.GetLiquidData().Color); // _activeLiquidDatas.Add(liquid); // } // // private void OnReleaseLiquidObject(Liquid liquid) // { // liquid.gameObject.SetActive(false); // _activeLiquidDatas.Remove(liquid); // } // // private void OnDestroyLiquidObject(Liquid liquid) // { // Destroy(liquid.gameObject); // _activeLiquidDatas.Remove(liquid); // } // // // 가니쉬 오브젝트 풀 // private Garnish CreateGarnishObject() // { // var instance = Instantiate(_garnishObject, _spawnTransform.position, Quaternion.identity, _spawnLocation); // instance.SetManagedPool(_garnishObjectPool); // return instance; // } // // private void OnGetGarnishObject(Garnish garnish) // { // _instanceLiquidCount++; // garnish.Initialize(_spawnTransform.position, Quaternion.identity, _reachedCollider, _pushDirection.normalized * _pushPower, _currentBarrel.GetLiquidData().Sprite); // _activeGarnishDatas.Add(garnish); // } // // private void OnReleaseGarnishObject(Garnish garnish) // { // garnish.gameObject.SetActive(false); // _activeGarnishDatas.Remove(garnish); // } // // private void OnDestroyGarnishObject(Garnish garnish) // { // Destroy(garnish.gameObject); // _activeGarnishDatas.Remove(garnish); // } // // #endregion // // // Custom methods // #region Custom methods // // /// // /// 술 제조 과정 초기화 함수 // /// // public void ReleaseAllObject() // { // // 리스트 삭제는 뒤에서부터 해야 오류가 없음 // for (var i = _activeLiquidDatas.Count - 1; i >= 0; i--) // { // _activeLiquidDatas[i].Destroy(); // } // // _liquidDataCounts.Clear(); // _isCompleted = false; // _instanceLiquidCount = 0; // _instanceMaterial.SetFloat(LiquidAmountHash, 0f); // SetCurrentAmount(0f); // HidePanel(); // } // // public void ReleaseAllObject(CocktailData cocktailData) // { // ReleaseAllObject(); // } // // public void ReleaseAllObject(CocktailData cocktailData, bool isServedPlayer) // { // if (!isServedPlayer) return; // // ReleaseAllObject(); // } // // public void HandleBarrelInteraction(Barrel barrel) // { // _currentBarrel = barrel; // if (_instanceLiquidCount == 0) // { // ShowPanelStarted(); // _shaker.SetActive(true); // _amountText.enabled = true; // _completeCocktailImage.enabled = false; // _completeText.enabled = false; // _isCompleted = false; // _currentMixedColor = barrel.GetLiquidData().Color; // _instanceMaterial.SetColor(LiquidColorHash, _currentMixedColor * _colorIntensity); // _reachedCollider.transform.position = _originalReachedPosition; // EventManager.InvokeCocktailStarted(); // } // else if (_instanceLiquidCount >= _maxLiquidCount) // { // return; // } // // _elapsedTime = 0f; // _isPouring = true; // AudioManager.Instance.PlaySfx(_pouringSfxName); // // // To Center 이동 코루틴이 활성화 중이지 않을 때 // if (_movePanelToCenterInstance == null) // { // // To Player 이동 코루틴이 활성화 중이라면 멈추고 To Center 활성화 // if (_movePanelToPlayerInstance != null) // { // StopCoroutine(_movePanelToPlayerInstance); // _movePanelToPlayerInstance = null; // } // Utils.StartUniqueCoroutine(this, ref _movePanelToCenterInstance, MovePanelToCenter()); // } // } // // public void HandleBarrelCancelInteraction() // { // _isPouring = false; // AudioManager.Instance.StopSfx(_pouringSfxName); // // Utils.StartUniqueCoroutine(this, ref _movePanelToPlayerInstance, MovePanelToPlayer()); // } // // private void SetCurrentAmount(float value) // { // _currentLiquidAmount = value; // // if (_amountText) // { // var percent = (int)(_currentLiquidAmount / _maxLiquidCount * 100); // _amountText.text = $"{percent}%"; // } // else // { // if (_amountText.enabled) // { // _amountText.enabled = false; // } // } // } // // /// // /// 술을 완성한 경우 // /// // private IEnumerator CompleteCocktail() // { // _isCompleted = true; // HandleBarrelCancelInteraction(); // // yield return new WaitUntil(() => _currentLiquidAmount >= _maxLiquidCount); // // var currentCocktailIngredients = new List(7); // foreach (var element in _liquidDataCounts) // { // var idx = element.Key.Idx; // var amount = element.Value; // currentCocktailIngredients.Add(new CocktailIngredient(idx, amount)); // } // // // ItemManager를 통해 모든 CocktailData 가져오기 // var cocktailDatas = ItemManager.Instance.CocktailDataSo.GetData(); // CocktailData matchingCocktail = null; // // // 모든 칵테일 데이터를 순회하면서 조건에 맞는 칵테일 찾기 // foreach (var cocktailData in cocktailDatas.Values) // { // var validIngredients = cocktailData.ValidIngredients; // // // 조건 1: 재료 개수 동일 체크 // if (validIngredients.Count != currentCocktailIngredients.Count) // continue; // // var allIngredientsMatch = true; // // // 현재 음료 재료를 하나씩 validIngredients와 비교 // foreach (var currentIngredient in currentCocktailIngredients) // { // // 동일한 Idx를 가진 재료가 있는지 찾음 // var matchingValidIngredient = validIngredients.FirstOrDefault(ingredient => ingredient.Idx == currentIngredient.Idx); // // // 만약 Idx가 일치하는 재료가 없으면 조건 불충족 // if (matchingValidIngredient == null) // { // allIngredientsMatch = false; // break; // } // // // 조건 2: Amount 값이 RatioRange에 따른 오차 범위 내에 있는지 체크 // var validAmount = matchingValidIngredient.Amount; // //var maxLiquidCount = cocktailData.GetCocktailAmount(validIngredients); // var range = _maxLiquidCount / 100 * cocktailData.RatioRange; // var minAmount = validAmount - range; // var maxAmount = validAmount + range; // // if (currentIngredient.Amount < minAmount || currentIngredient.Amount > maxAmount) // { // allIngredientsMatch = false; // break; // } // } // // // 조건이 모두 만족하면 매칭되는 칵테일을 찾음 // if (allIngredientsMatch) // { // matchingCocktail = cocktailData; // break; // } // } // // // 조건에 만족하는 칵테일이 없음 // if (matchingCocktail == null) // { // //matchingCocktail = ItemManager.Instance.CocktailDataSo.GetDataByIdx("Cocktail000"); // _completeText.text = Utils.GetLocalizedString("Failure"); // AudioManager.Instance.PlaySfx(_failedMakingCocktailSfxName); // } // else // { // _completeText.text = $"{Utils.GetLocalizedString("Success")}!\n{Utils.GetLocalizedString(matchingCocktail.Idx)}"; // AudioManager.Instance.PlaySfx(_succeedMakingCocktailSfxName); // } // // _shaker.SetActive(false); // _amountText.enabled = false; // _completeCocktailImage.sprite = matchingCocktail.Sprite; // _completeCocktailImage.enabled = true; // _completeText.enabled = true; // // yield return new WaitForSeconds(1f); // // HidePanel(); // EventManager.InvokeCocktailCompleted(matchingCocktail, true); // } // // /// // /// 사용된 색상의 비율에 맞게 색을 혼합시키는 함수 // /// // private Color MixColorsByTime() // { // var totalCounts = _liquidDataCounts.Values.Sum(); // // var mixedColor = Color.black; // // foreach (var element in _liquidDataCounts) // { // var color = element.Key.Color; // var count = element.Value; // var ratio = count / (float)totalCounts; // // mixedColor += color * ratio; // } // // mixedColor.a = 1f; // // return mixedColor; // } // // /// // /// 액체가 특정 오브젝트에 충돌했을 때, 실행해야하는 과정 // /// // public void OnTargetReached() // { // _liquidReachedTime = Time.time; // SetCurrentAmount(++_currentLiquidAmount); // var liquidAmount = Mathf.Clamp(_currentLiquidAmount / _maxLiquidCount, 0f, 1f); // var reachedColliderPositionY = Mathf.Lerp(_reachedLerpPosition.x, _reachedLerpPosition.y, liquidAmount); // _reachedCollider.transform.position = new Vector3(_reachedCollider.transform.position.x, // reachedColliderPositionY, _reachedCollider.transform.position.z); // _instanceMaterial.SetFloat(LiquidAmountHash, liquidAmount); // _targetColor = MixColorsByTime(); // // if (liquidAmount >= 1f) // { // HandleBarrelCancelInteraction(); // } // } // // public void ShowPanelStarted() // { // if (_isShowingPanel) return; // // _liquidPanel.transform.localScale = _originalPanelScale; // _liquidPanel.transform.position = _centerPosition; // _balloonImage.sprite = _centerBalloonImage; // _liquidPanel.SetActive(true); // _isShowingPanel = true; // } // // private IEnumerator MovePanelToPlayer() // { // if (_isCompleted) // { // _movePanelToPlayerInstance = null; // yield break; // } // // yield return new WaitUntil(() => _activeLiquidDatas.Count == 0 && _activeGarnishDatas.Count == 0); // // var startScale = _liquidPanel.transform.localScale; // var startPosition = _liquidPanel.transform.position; // Camera mainCamera = TycoonCameraManager.Instance.MainCamera; // // var elapsedTime = 0f; // while (elapsedTime <= _moveToPlayerDuration) // { // var playerPosition = _tycoonPlayer.transform.position; // var distance = Vector3.Distance(playerPosition, mainCamera.transform.position); // float t = Mathf.InverseLerp(_cameraDistance.x, _cameraDistance.y, distance); // float offsetY = Mathf.Lerp(_offsetY.x, _offsetY.y, t); // var playerViewportPoint = mainCamera.WorldToViewportPoint(playerPosition); // var panelWorldPosition = _overlayCamera.ViewportToWorldPoint(new Vector3(playerViewportPoint.x, // playerViewportPoint.y, playerViewportPoint.z)); // panelWorldPosition.y += offsetY; // // var lerpTime = elapsedTime / _moveToPlayerDuration; // _liquidPanel.transform.position = Vector3.Lerp(startPosition, panelWorldPosition, lerpTime); // _liquidPanel.transform.localScale = Vector3.Lerp(startScale, _endScale, lerpTime); // // elapsedTime += Time.deltaTime; // yield return null; // } // // _balloonImage.sprite = _playerBalloonImage; // _liquidPanel.transform.localScale = _endScale; // // // 완성되지 않았거나, 따르고 있지 않으면 플레이어를 추적함 // var waitTime = new WaitForFixedUpdate(); // while (!_isCompleted && !_isPouring) // { // var playerPosition = _tycoonPlayer.transform.position; // var distance = Vector3.Distance(playerPosition, mainCamera.transform.position); // float t = Mathf.InverseLerp(_cameraDistance.x, _cameraDistance.y, distance); // float offsetY = Mathf.Lerp(_offsetY.x, _offsetY.y, t); // var playerViewportPoint = mainCamera.WorldToViewportPoint(playerPosition); // var panelWorldPosition = _overlayCamera.ViewportToWorldPoint(new Vector3(playerViewportPoint.x, // playerViewportPoint.y, playerViewportPoint.z)); // panelWorldPosition.y += offsetY; // // _liquidPanel.transform.position = panelWorldPosition; // yield return waitTime; // } // // _movePanelToPlayerInstance = null; // } // // private IEnumerator MovePanelToCenter() // { // _balloonImage.sprite = _centerBalloonImage; // var startScale = _liquidPanel.transform.localScale; // var startPosition = _liquidPanel.transform.position; // var elapsedTime = 0f; // while (elapsedTime <= _moveToCenterDuration) // { // var lerpTime = elapsedTime / _moveToCenterDuration; // _liquidPanel.transform.position = Vector3.Lerp(startPosition, _centerPosition, lerpTime); // _liquidPanel.transform.localScale = Vector3.Lerp(startScale, _originalPanelScale, lerpTime); // // elapsedTime += Time.deltaTime; // yield return null; // } // // _liquidPanel.transform.position = _centerPosition; // _liquidPanel.transform.localScale = _originalPanelScale; // _movePanelToCenterInstance = null; // } // // public void HidePanel() // { // if (!_isShowingPanel) return; // // _isShowingPanel = false; // _liquidPanel.SetActive(false); // } // // #endregion // } // }