using System; using System.Collections.Generic; using Sirenix.OdinInspector; using Unity.Cinemachine; using UnityEngine; using UnityEngine.Serialization; namespace BlueWater { public enum TycoonCameraType { Base = 0, Storage } 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 StorageCamera { get; private set; } [SerializeField] private Transform _confinerCollider; [SerializeField] private Vector3 _transparencySortAxis; [Title("줌")] [SerializeField] private Vector2 _cameraDistance = new(5f, 10f); [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); // Variables private CinemachineBrain _cinemachineBrain; private CinemachinePositionComposer _baseCameraComposer; private List _cinemachineCameras = new(); private float _targetCameraDistance; #endregion // Unity events #region Unity events private void OnValidate() { SetTransparencySortAxis(); } protected override void OnAwake() { Initialize(); } private void Start() { _targetCameraDistance = _baseCameraComposer.CameraDistance; EventManager.OnCameraZoomOut += ZoomOut; EventManager.OnCameraZoomIn += ZoomIn; if (!GameManager.Instance) return; GameManager.Instance.OnInstantiatePlayer += SetFollow; } private void LateUpdate() { 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.OnCameraZoomOut -= ZoomOut; EventManager.OnCameraZoomIn -= ZoomIn; if (!GameManager.Instance) return; GameManager.Instance.OnInstantiatePlayer -= SetFollow; } #endregion // Initialize methods #region Initialize methods [Button("셋팅 초기화")] private void Initialize() { cameraLocation = GameObject.Find("CinemachineCameras").transform; MainCamera = GetComponent(); UiCamera = MainCamera.transform.Find("UiCamera").GetComponent(); LiquidOverlayCamera = GameObject.Find("LiquidOverlayCamera").GetComponent(); _cinemachineBrain = GetComponent(); BaseCamera = cameraLocation.Find("BaseCamera").GetComponent(); StorageCamera = cameraLocation.Find("StorageCamera").GetComponent(); _baseCameraComposer = BaseCamera.GetComponent(); _cinemachineCameras.Add(BaseCamera); _cinemachineCameras.Add(StorageCamera); 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.Storage => StorageCamera, _ => throw new ArgumentOutOfRangeException(nameof(tycoonCameraType), tycoonCameraType, null) }; foreach (var element in _cinemachineCameras) { element.Priority = 0; } newMainCamera.Priority = 1; SetTransparencySortAxis(); } private void SetTransparencySortAxis() { var camera = Camera.main; camera.transparencySortMode = TransparencySortMode.CustomAxis; camera.transparencySortAxis = _transparencySortAxis; } public void ZoomOut(float value) { _targetCameraDistance = Mathf.Min( _targetCameraDistance + value * _zoomPower, _cameraDistance.y ); } public void ZoomIn(float value) { _targetCameraDistance = Mathf.Max( _targetCameraDistance - value * _zoomPower, _cameraDistance.x ); } #endregion } }