using System.Collections; using UnityEngine; using Colosseum.Enemy; namespace Colosseum.Effects { /// /// 보스 승리 연출 이펙트. /// 보스 사망 시 카메라 연출, 이펙트, 슬로우 모션 등을 처리합니다. /// GameManager에 의해 활성화됩니다. /// public class VictoryEffect : MonoBehaviour { [Header("Victory Settings")] [Tooltip("승리 시 슬로우 모션 배율")] [SerializeField] private float slowMotionScale = 0.3f; [Tooltip("슬로우 모션 지속 시간")] [SerializeField] private float slowMotionDuration = 2f; [Header("Effects")] [Tooltip("승리 시 생성할 이펙트 프리팹")] [SerializeField] private GameObject victoryEffectPrefab; [Tooltip("이펙트 생성 위치 오프셋")] [SerializeField] private Vector3 effectOffset = Vector3.up * 2f; [Header("Audio")] [Tooltip("승리 사운드")] [SerializeField] private AudioClip victorySound; [Tooltip("사운드 볼륨")] [SerializeField] private float soundVolume = 1f; [Header("Debug")] [SerializeField] private bool debugMode = true; // 상태 private bool isPlaying = false; private float originalTimeScale; private Camera mainCamera; private void Awake() { mainCamera = Camera.main; } private void OnEnable() { PlayVictoryEffect(); } private void OnDisable() { // 시간 스케일 복구 if (isPlaying) { Time.timeScale = 1f; isPlaying = false; } } /// /// 승리 연출 재생 /// public void PlayVictoryEffect() { if (isPlaying) return; StartCoroutine(VictorySequence()); } private IEnumerator VictorySequence() { isPlaying = true; originalTimeScale = Time.timeScale; if (debugMode) { Debug.Log("[VictoryEffect] Starting victory sequence"); } // 1. 슬로우 모션 yield return StartCoroutine(PlaySlowMotion()); // 2. 카메라 연출 yield return StartCoroutine(PlayCameraEffect()); // 3. 이펙트 생성 SpawnVictoryEffect(); // 4. 사운드 재생 PlayVictorySound(); // 5. 시간 복구 Time.timeScale = originalTimeScale; isPlaying = false; if (debugMode) { Debug.Log("[VictoryEffect] Victory sequence complete"); } } private IEnumerator PlaySlowMotion() { float elapsed = 0f; while (elapsed < slowMotionDuration) { elapsed += Time.unscaledDeltaTime; float t = elapsed / slowMotionDuration; // 처음에는 슬로우, 나중에는 복구 if (t < 0.5f) { Time.timeScale = Mathf.Lerp(originalTimeScale, slowMotionScale, t * 2f); } else { Time.timeScale = Mathf.Lerp(slowMotionScale, originalTimeScale, (t - 0.5f) * 2f); } yield return null; } Time.timeScale = slowMotionScale; } private IEnumerator PlayCameraEffect() { if (mainCamera == null || BossEnemy.ActiveBoss == null) yield break; // 보스 위치로 카메라 이동 Transform bossTransform = BossEnemy.ActiveBoss.transform; Vector3 targetPosition = bossTransform.position + effectOffset; float elapsed = 0f; float duration = slowMotionDuration * 0.5f; while (elapsed < duration) { elapsed += Time.unscaledDeltaTime; // 카메라가 보스를 바라보도록 mainCamera.transform.LookAt(targetPosition); yield return null; } } private void SpawnVictoryEffect() { if (victoryEffectPrefab == null) return; Vector3 spawnPosition = transform.position + effectOffset; if (BossEnemy.ActiveBoss != null) { spawnPosition = BossEnemy.ActiveBoss.transform.position + effectOffset; } var effect = Instantiate(victoryEffectPrefab, spawnPosition, Quaternion.identity); // 일정 시간 후 제거 Destroy(effect, 5f); if (debugMode) { Debug.Log("[VictoryEffect] Spawned victory effect"); } } private void PlayVictorySound() { if (victorySound == null) return; AudioSource.PlayClipAtPoint(victorySound, transform.position, soundVolume); if (debugMode) { Debug.Log("[VictoryEffect] Played victory sound"); } } } }