버그 수정
This commit is contained in:
@@ -1,10 +1,20 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Playables;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
public class LocalManager : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private string _nextSceneName;
|
||||
[SerializeField] private AudioClip _caffebeneBGM;
|
||||
|
||||
// 흑백 전환에 걸리는 시간(초)
|
||||
[SerializeField, Min(0f)] private float _grayscaleFadeTime = 1.5f;
|
||||
// BGM 재생 시작 후 씬 전환까지 대기 시간(초)
|
||||
[SerializeField, Min(0f)] private float _caffebeneSceneChangeDelay = 13f;
|
||||
|
||||
private VolumeProfile _grayscaleProfile;
|
||||
|
||||
public void NextScene(int delay)
|
||||
{
|
||||
_ = Util.RunDelayed((float)delay,()=>SceneLoadManager.Instance.RequestSceneChange(_nextSceneName));
|
||||
@@ -12,7 +22,75 @@ public void NextScene(int delay)
|
||||
|
||||
public void CaffebeneNextSceneChange()
|
||||
{
|
||||
SoundManager.Instance.PlayOverrideBGM(_caffebeneBGM);
|
||||
_ = Util.RunDelayed(13f,()=>SceneLoadManager.Instance.RequestSceneChange(_nextSceneName));
|
||||
_ = CaffebeneSequence();
|
||||
}
|
||||
|
||||
// 모든 애니메이션 정지 → 시야 흑백 페이드 → BGM 재생 → 대기 후 씬 전환
|
||||
private async Awaitable CaffebeneSequence()
|
||||
{
|
||||
try
|
||||
{
|
||||
PauseAllAnimations();
|
||||
|
||||
await FadeToGrayscale(_grayscaleFadeTime);
|
||||
|
||||
SoundManager.Instance.PlayOverrideBGM(_caffebeneBGM);
|
||||
|
||||
await Awaitable.WaitForSecondsAsync(_caffebeneSceneChangeDelay, destroyCancellationToken);
|
||||
SceneLoadManager.Instance.RequestSceneChange(_nextSceneName);
|
||||
}
|
||||
catch (System.OperationCanceledException)
|
||||
{
|
||||
// 씬 전환 등으로 자신이 파괴되어 취소됨
|
||||
}
|
||||
}
|
||||
|
||||
// 씬 안의 Animator / 타임라인 / 파티클을 전부 일시정지
|
||||
// (Time.timeScale은 건드리지 않는다 — BGM 페이드와 씬 전환 딜레이가 scaled time 기준이라 함께 멈춰버림)
|
||||
private static void PauseAllAnimations()
|
||||
{
|
||||
foreach (var animator in FindObjectsByType<Animator>())
|
||||
animator.speed = 0f;
|
||||
|
||||
foreach (var director in FindObjectsByType<PlayableDirector>())
|
||||
director.Pause();
|
||||
|
||||
foreach (var particle in FindObjectsByType<ParticleSystem>())
|
||||
particle.Pause();
|
||||
}
|
||||
|
||||
// 런타임 전용 글로벌 볼륨을 만들어 채도를 0 → -100으로 페이드 (완전 흑백)
|
||||
private async Awaitable FadeToGrayscale(float duration)
|
||||
{
|
||||
var volumeObj = new GameObject("Grayscale Volume (Runtime)");
|
||||
var volume = volumeObj.AddComponent<Volume>();
|
||||
volume.isGlobal = true;
|
||||
volume.priority = 100f;
|
||||
|
||||
_grayscaleProfile = ScriptableObject.CreateInstance<VolumeProfile>();
|
||||
var colorAdjustments = _grayscaleProfile.Add<ColorAdjustments>();
|
||||
colorAdjustments.saturation.Override(0f);
|
||||
volume.profile = _grayscaleProfile;
|
||||
|
||||
// 카메라에 포스트 프로세싱이 꺼져 있으면 켠다
|
||||
var mainCam = Camera.main;
|
||||
if (mainCam != null)
|
||||
mainCam.GetUniversalAdditionalCameraData().renderPostProcessing = true;
|
||||
|
||||
float timer = 0f;
|
||||
while (timer < duration)
|
||||
{
|
||||
timer += Time.deltaTime;
|
||||
colorAdjustments.saturation.value = Mathf.Lerp(0f, -100f, Mathf.Clamp01(timer / duration));
|
||||
await Awaitable.NextFrameAsync(destroyCancellationToken);
|
||||
}
|
||||
colorAdjustments.saturation.value = -100f;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
// 런타임 생성한 프로필은 씬 언로드로 자동 파괴되지 않으므로 직접 정리
|
||||
if (_grayscaleProfile != null)
|
||||
Destroy(_grayscaleProfile);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user