using System.Collections; using System.Collections.Generic; using Platformer.Gameplay; using UnityEngine; using static Platformer.Core.Simulation; namespace Platformer.Mechanics { /// /// 낙사 영역 — PD 지시 2026-05-07: 즉사 폐기 → HP 감소 + 위치 복귀 + 1초 무적. /// 추가 (#3): 캐릭터가 카메라 영역 밖으로 완전히 사라진 후 위치 복귀 (낙하 자연스러움). /// public class DeathZone : MonoBehaviour { public int fallDamage = 1; public float fallInvulnerability = 1f; /// 카메라 영역 외 대기 timeout(초). 안전망 — 카메라 영역 영역 외로 안 사라지는 경우 강제 진행. public float fallTimeout = 3f; readonly HashSet falling = new HashSet(); void OnTriggerEnter2D(Collider2D collider) { var p = collider.gameObject.GetComponent(); if (p == null || p.health == null) return; if (falling.Contains(p)) return; // 이미 처리 중이면 중복 방지 falling.Add(p); StartCoroutine(FallSequence(p)); } IEnumerator FallSequence(PlayerController p) { // 입력 차단 (낙하 중에는 조작 불가) p.controlEnabled = false; // 카메라 영역 외 (viewport y < 0)까지 대기 — PD 지시 2026-05-07 #3 Camera cam = Camera.main; float deadline = Time.time + fallTimeout; while (Time.time < deadline) { if (cam != null) { Vector3 viewport = cam.WorldToViewportPoint(p.transform.position); if (viewport.y < -0.1f) break; } yield return null; } // 위치 복귀 + HP 감소 + 1초 무적 (PD 지시 2026-05-07 — 낙사 복귀 시 hit 모션 X → DecrementSilent) p.transform.position = p.LastGroundedPosition; p.velocity = Vector2.zero; p.health.DecrementSilent(fallDamage); if (p.health.IsAlive) { p.health.GrantInvulnerability(fallInvulnerability); p.controlEnabled = true; } // IsAlive == false면 ResurrectPromptUI가 OnDeathEvent로 자동 처리 (controlEnabled false 유지) falling.Remove(p); } } }