CapersProject/Assets/02.Scripts/PostProcessingManager.cs
2025-03-02 15:44:36 +09:00

181 lines
5.6 KiB
C#

using System;
using System.Collections;
using DDD.Utility;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public enum RendererFeatureName
{
None = 0,
GrayscaleRenderPassFeature
}
public enum VolumeType
{
None = 0,
Global,
Player
}
public class PostProcessingManager : Singleton<PostProcessingManager>
{
[SerializeField]
public Volume _globalVolume;
[SerializeField]
private Volume _playerVolume;
[SerializeField]
private UniversalRenderPipelineAsset _currentRenderPipeline;
[SerializeField]
private ScriptableRendererData _currentRenderData;
private Coroutine _lowHpVignetteCoroutine;
// LowHpVignette
[Title("LowHpVignette")]
[SerializeField]
private bool _isLerpIntensity = true;
[SerializeField]
private float _startIntensity = 0.15f;
[SerializeField, ShowIf("@_isLerpIntensity")]
private float _endIntensity = 0.2f;
[SerializeField, ShowIf("@_isLerpIntensity")]
private float _lerpTime = 1f;
protected override void OnAwake()
{
InitializeComponents();
}
protected override void OnApplicationQuit()
{
ToggleRendererFeature(RendererFeatureName.GrayscaleRenderPassFeature, false);
}
[Button("컴포넌트 초기화")]
private void InitializeComponents()
{
_currentRenderPipeline = (UniversalRenderPipelineAsset)GraphicsSettings.currentRenderPipeline;
_currentRenderData = _currentRenderPipeline.rendererDataList[0];
_globalVolume = GetComponent<Volume>();
_playerVolume = transform.Find("PlayerVolume").GetComponent<Volume>();
}
public void ToggleRendererFeature(RendererFeatureName featureName, bool value)
{
foreach (var element in _currentRenderData.rendererFeatures)
{
if (!string.Equals(element.name, featureName.ToString())) continue;
element.SetActive(value);
return;
}
Debug.Log($"{featureName}과 일치하는 기능이 없습니다.");
}
public void ToggleEffect<T>(bool value, VolumeType volumeType) where T : VolumeComponent
{
Volume currentVolume = null;
switch (volumeType)
{
case VolumeType.None:
break;
case VolumeType.Global:
currentVolume = _globalVolume;
break;
case VolumeType.Player:
currentVolume = _playerVolume;
break;
default:
throw new ArgumentOutOfRangeException(nameof(volumeType), volumeType, null);
}
if (!currentVolume)
{
Debug.LogError($"VolumeType : {volumeType}의 {currentVolume}이 존재하지 않습니다.");
return;
}
var effect = GetEffect<T>(volumeType);
if (!effect)
{
print(typeof(T) + "효과가 없습니다.");
return;
}
effect.active = value;
}
private T GetEffect<T>(VolumeType volumeType) where T : VolumeComponent
{
Volume currentVolume = null;
switch (volumeType)
{
case VolumeType.None:
break;
case VolumeType.Global:
currentVolume = _globalVolume;
break;
case VolumeType.Player:
currentVolume = _playerVolume;
break;
default:
throw new ArgumentOutOfRangeException(nameof(volumeType), volumeType, null);
}
if (!currentVolume)
{
Debug.LogError($"VolumeType : {volumeType}의 {currentVolume}이 존재하지 않습니다.");
return null;
}
currentVolume.profile.TryGet(out T effect);
return effect;
}
public void LowHpVignette()
{
Utils.StartUniqueCoroutine(this, ref _lowHpVignetteCoroutine, LowHpVignetteCoroutine());
}
public void DefaultHpVignette()
{
Utils.EndUniqueCoroutine(this, ref _lowHpVignetteCoroutine);
ToggleEffect<Vignette>(false, VolumeType.Player);
}
private IEnumerator LowHpVignetteCoroutine()
{
var vignette = GetEffect<Vignette>(VolumeType.Player);
vignette.intensity.value = _startIntensity;
vignette.active = true;
if (!_isLerpIntensity) yield break;
var elapsedTime = 0f;
var addTime = Time.deltaTime;
while (true)
{
vignette.intensity.value = Mathf.Lerp(_startIntensity, _endIntensity, elapsedTime / _lerpTime);
if (elapsedTime > _lerpTime)
{
addTime = -Time.deltaTime;
}
else if (elapsedTime < 0)
{
addTime = Time.deltaTime;
}
elapsedTime += addTime;
yield return null;
}
}
public void DepthOfFieldButton(bool active) => ToggleEffect<DepthOfField>(active, VolumeType.Global);
}