EerieVillage/Assets/Scripts/Mechanics/DeathZone.cs

65 lines
2.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Platformer.Gameplay;
using UnityEngine;
using static Platformer.Core.Simulation;
namespace Platformer.Mechanics
{
/// <summary>
/// 낙사 영역 — PD 지시 2026-05-07: 즉사 폐기 → HP 감소 + 위치 복귀 + 1초 무적.
/// 추가 (#3): 캐릭터가 카메라 영역 밖으로 완전히 사라진 후 위치 복귀 (낙하 자연스러움).
/// </summary>
public class DeathZone : MonoBehaviour
{
public int fallDamage = 1;
public float fallInvulnerability = 1f;
/// <summary>카메라 영역 외 대기 timeout(초). 안전망 — 카메라 영역 영역 외로 안 사라지는 경우 강제 진행.</summary>
public float fallTimeout = 3f;
readonly HashSet<PlayerController> falling = new HashSet<PlayerController>();
void OnTriggerEnter2D(Collider2D collider)
{
var p = collider.gameObject.GetComponent<PlayerController>();
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초 무적
p.transform.position = p.LastGroundedPosition;
p.velocity = Vector2.zero;
p.health.Decrement(fallDamage);
if (p.health.IsAlive)
{
p.health.GrantInvulnerability(fallInvulnerability);
p.controlEnabled = true;
}
// IsAlive == false면 ResurrectPromptUI가 OnDeathEvent로 자동 처리 (controlEnabled false 유지)
falling.Remove(p);
}
}
}