using System; using System.Collections.Generic; using Sirenix.OdinInspector; using Unity.Cinemachine; using UnityEngine; using UnityEngine.InputSystem; namespace DDD { public enum TycoonCameraType { Base = 0, Favorability01 = 1, Favorability02 = 2 } public class TycoonCameraManager : Singleton { // Components #region Components [Title("카메라")] [field: SerializeField] public Camera MainCamera { get; private set; } [field: SerializeField] public Camera UiCamera { get; private set; } [field: SerializeField] public Camera LiquidOverlayCamera { get; private set; } [SerializeField] private Transform cameraLocation; [field: SerializeField] public CinemachineCamera BaseCamera { get; private set; } [field: SerializeField] public CinemachineCamera FavorabilityCamera01 { get; private set; } [field: SerializeField] public CinemachineCamera FavorabilityCamera02 { get; private set; } [SerializeField] private Transform _confinerCollider; [SerializeField] private Vector3 _transparencySortAxis; [Title("줌")] [SerializeField] private Vector2 _cameraDistance = new(5f, 10f); [SerializeField] private float _initializedDistance = 7f; [SerializeField, Range(0.01f, 1f)] private float _zoomPower = 0.5f; [SerializeField, Range(1f, 10f)] private float _zoomLerpSpeed = 5f; [SerializeField] private Vector3 _zoomOutConfinerScale = new(1f, 1f, 0f); [SerializeField] private Vector3 _zoomInConfinerScale = new(10f, 10f, 10f); private TycoonCameraType _currentTycoonCameraType; // Variables private CinemachineBrain _cinemachineBrain; private CinemachinePositionComposer _baseCameraComposer; private List _cinemachineCameras = new(); private InputAction _zoomInAction; private InputAction _zoomOutAction; private float _targetCameraDistance; #endregion // Unity events #region Unity events private void OnValidate() { SetTransparencySortAxis(); } protected override void OnAwake() { Initialize(); } private void Start() { EventManager.OnMoveRestaurant += MoveRestaurant; EventManager.OnMoveFavorability01 += MoveFavorability01; EventManager.OnMoveFavorability02 += MoveFavorability02; _zoomInAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.Tycoon, TycoonActions.ZoomIn); _zoomOutAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.Tycoon, TycoonActions.ZoomOut); _zoomInAction.performed += OnZoomChanged; _zoomOutAction.performed += OnZoomChanged; _zoomInAction.canceled += OnZoomChanged; _zoomOutAction.canceled += OnZoomChanged; _targetCameraDistance = _initializedDistance; _baseCameraComposer.CameraDistance = _initializedDistance; } private void LateUpdate() { if (_currentTycoonCameraType != TycoonCameraType.Base) return; var lerpTime = Time.deltaTime * _zoomLerpSpeed; _baseCameraComposer.CameraDistance = Mathf.Lerp( _baseCameraComposer.CameraDistance, _targetCameraDistance, lerpTime ); var normalizedT = (_baseCameraComposer.CameraDistance - _cameraDistance.x) / (_cameraDistance.y - _cameraDistance.x); _confinerCollider.localScale = Vector3.Lerp( _zoomInConfinerScale, _zoomOutConfinerScale, normalizedT ); } private void OnDestroy() { EventManager.OnMoveRestaurant -= MoveRestaurant; EventManager.OnMoveFavorability01 -= MoveFavorability01; EventManager.OnMoveFavorability02 -= MoveFavorability02; _zoomInAction.performed -= OnZoomChanged; _zoomOutAction.performed -= OnZoomChanged; _zoomInAction.canceled -= OnZoomChanged; _zoomOutAction.canceled -= OnZoomChanged; } #endregion // Initialize methods #region Initialize methods [Button("셋팅 초기화")] private void Initialize() { cameraLocation = GameObject.Find("CinemachineCameras").transform; MainCamera = GetComponent(); UiCamera = MainCamera.transform.Find("UiCamera").GetComponent(); _cinemachineBrain = GetComponent(); _baseCameraComposer = BaseCamera.GetComponent(); _cinemachineCameras.Add(BaseCamera); _cinemachineCameras.Add(FavorabilityCamera01); _cinemachineCameras.Add(FavorabilityCamera02); SetMainCamera(TycoonCameraType.Base); } #endregion // Methods #region Methods public void SetFollow(Transform target) { BaseCamera.Follow = target; } public void SetMainCamera(TycoonCameraType tycoonCameraType) { var newMainCamera = tycoonCameraType switch { TycoonCameraType.Base => BaseCamera, TycoonCameraType.Favorability01 => FavorabilityCamera01, TycoonCameraType.Favorability02 => FavorabilityCamera02, _ => throw new ArgumentOutOfRangeException(nameof(tycoonCameraType), tycoonCameraType, null) }; foreach (var element in _cinemachineCameras) { element.Priority = 0; } _currentTycoonCameraType = tycoonCameraType; newMainCamera.Priority = 1; SetTransparencySortAxis(); } private void SetTransparencySortAxis() { var camera = Camera.main; camera.transparencySortMode = TransparencySortMode.CustomAxis; camera.transparencySortAxis = _transparencySortAxis; } private void OnZoomChanged(InputAction.CallbackContext context) { if (_currentTycoonCameraType != TycoonCameraType.Base) return; var zoomDirection = _zoomOutAction.ReadValue() - _zoomInAction.ReadValue(); _targetCameraDistance = Mathf.Clamp( _targetCameraDistance + zoomDirection * _zoomPower, _cameraDistance.x, _cameraDistance.y ); } public float GetCurrentBaseCameraDistance() { return _baseCameraComposer.CameraDistance; } public void MoveRestaurant() { _cinemachineBrain.DefaultBlend = new CinemachineBlendDefinition(CinemachineBlendDefinition.Styles.Cut, 0f); SetMainCamera(TycoonCameraType.Base); } public void MoveFavorability01() { _cinemachineBrain.DefaultBlend = new CinemachineBlendDefinition(CinemachineBlendDefinition.Styles.Cut, 0f); SetMainCamera(TycoonCameraType.Favorability01); } public void MoveFavorability02() { _cinemachineBrain.DefaultBlend = new CinemachineBlendDefinition(CinemachineBlendDefinition.Styles.Cut, 0f); SetMainCamera(TycoonCameraType.Favorability02); } #endregion } }