using System.Collections; using System.Collections.Generic; using Cinemachine; using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; // ReSharper disable once CheckNamespace namespace BlueWaterProject { public class OceanCamera : MonoBehaviour { [Title("초기화 방식")] [SerializeField] private bool autoInit = true; [field: Title("카메라")] [field: SerializeField] public CinemachineVirtualCamera BaseShipCam { get; private set; } [Title("포스트 프로세싱")] [SerializeField] private Color boostVignetteColor = Color.red; [SerializeField] private Color boostIntermediateVignetteColor = Color.gray; [Range(0f, 4f)] [SerializeField] private float vignetteIntensity = 0.4f; private Vignette vignette; private Color defaultVignetteColor; private float defaultVignetteIntensity; private List cineCamList; private GameObject cineCams; private CinemachineFramingTransposer framingTransposer; private Coroutine distanceCoroutine; private float defaultDistance; private const int CINE_CAM_NUM = 1; private void Awake() { if (autoInit) { Init(); } CameraManager.Inst.OceanCamera = this; CameraManager.Inst.MainCam = Camera.main; vignette = GetEffect(); if (vignette) { defaultVignetteColor = vignette.color.value; defaultVignetteIntensity = vignette.intensity.value; } } [Button("셋팅 초기화")] private void Init() { cineCams = GameObject.Find("CineCameras"); if (!cineCams) { Debug.LogError("cineCams is null error"); return; } BaseShipCam = cineCams.transform.Find("BaseShipCam")?.GetComponent(); if (!BaseShipCam) { Debug.LogError("BaseShipCam is null error"); return; } framingTransposer = BaseShipCam.GetCinemachineComponent(); defaultDistance = framingTransposer.m_CameraDistance; cineCamList = new List(CINE_CAM_NUM) { BaseShipCam }; foreach (var cam in cineCamList) { cam.Priority = 0; } BaseShipCam.Priority = 1; CameraManager.Inst.MainCam = Camera.main; } public void ChangeDistance(float addDistance, float time) { if (distanceCoroutine != null) { StopCoroutine(distanceCoroutine); } distanceCoroutine = StartCoroutine(ChangeDistanceCoroutine(addDistance, time)); } private IEnumerator ChangeDistanceCoroutine(float addDistance, float time) { var changeDistance = framingTransposer.m_CameraDistance + addDistance; var updateTime = 0f; while (updateTime < time) { updateTime += Time.deltaTime; framingTransposer.m_CameraDistance = Mathf.Lerp(framingTransposer.m_CameraDistance, changeDistance, updateTime / time); yield return null; } yield return null; } public void DefaultDistance(float time) { if (distanceCoroutine != null) { StopCoroutine(distanceCoroutine); } distanceCoroutine = StartCoroutine(DefaultDistanceCoroutine(time)); } private IEnumerator DefaultDistanceCoroutine(float time) { var updateTime = 0f; while (updateTime < time) { updateTime += Time.deltaTime; framingTransposer.m_CameraDistance = Mathf.Lerp(framingTransposer.m_CameraDistance, defaultDistance, updateTime / time); yield return null; } framingTransposer.m_CameraDistance = defaultDistance; yield return null; } #region PostProcessing public void ToggleEffect(bool value) where T : VolumeComponent { var effect = GetEffect(); if (effect == null) { print(typeof(T) + "효과가 없습니다."); return; } effect.active = value; } private T GetEffect() where T : VolumeComponent { var postProcessVolume = FindAnyObjectByType(); if (postProcessVolume == null) { print("Volume 컴포넌트를 가진 오브젝트가 없습니다."); return null; } postProcessVolume.profile.TryGet(out T effect); return effect; } public void BoostVignette(float boostGauge) { if (boostGauge <= 0.3f) { vignette.color.value = Color.Lerp(defaultVignetteColor, boostIntermediateVignetteColor, boostGauge / 0.3f); } else { vignette.color.value = Color.Lerp(boostIntermediateVignetteColor, boostVignetteColor, (boostGauge - 0.3f) / 0.7f); vignette.intensity.value = Mathf.Lerp(defaultVignetteIntensity, vignetteIntensity, (boostGauge - 0.3f) / 0.7f); } } #endregion } }