diff --git a/Assets/Scripts/Mechanics/DeathZone.cs b/Assets/Scripts/Mechanics/DeathZone.cs index 3cb30a0..bf4edf1 100644 --- a/Assets/Scripts/Mechanics/DeathZone.cs +++ b/Assets/Scripts/Mechanics/DeathZone.cs @@ -47,10 +47,10 @@ namespace Platformer.Mechanics yield return null; } - // 위치 복귀 + HP 감소 + 1초 무적 + // 위치 복귀 + HP 감소 + 1초 무적 (PD 지시 2026-05-07 — 낙사 복귀 시 hit 모션 X → DecrementSilent) p.transform.position = p.LastGroundedPosition; p.velocity = Vector2.zero; - p.health.Decrement(fallDamage); + p.health.DecrementSilent(fallDamage); if (p.health.IsAlive) { diff --git a/Assets/Scripts/Mechanics/EnemyController.cs b/Assets/Scripts/Mechanics/EnemyController.cs index 2b25fd0..eadbf4a 100644 --- a/Assets/Scripts/Mechanics/EnemyController.cs +++ b/Assets/Scripts/Mechanics/EnemyController.cs @@ -19,8 +19,8 @@ namespace Platformer.Mechanics public float hitRangeX = 0.7f; /// Y 임계값. 위/아래 둘 다 인정. public float hitRangeY = 1.0f; - /// 밟기 판정 — Player가 Enemy보다 위 거리. - public float stompMinDy = 0.5f; + /// 밟기 판정 — Player가 Enemy보다 위 거리. 발 닿는 느낌 영역(0.05~0.15). + public float stompMinDy = 0.1f; internal PatrolPath.Mover mover; internal AnimationController control; diff --git a/Assets/Scripts/Mechanics/GameOptimizer.cs b/Assets/Scripts/Mechanics/GameOptimizer.cs index 453def1..5d6b2e7 100644 --- a/Assets/Scripts/Mechanics/GameOptimizer.cs +++ b/Assets/Scripts/Mechanics/GameOptimizer.cs @@ -18,15 +18,26 @@ namespace Platformer.Mechanics } /// - /// PD 지시 2026-05-07 — 모든 TilemapCollider2D를 One-Way Platform으로 자동 변환. - /// 위에서만 착지·측면·아래 통과 = 점프 시 천장 통과 + 이동 시 측면 벽 통과 + 착지/걷기는 지면 위 머무름. + /// PD 지시 2026-05-07 — 모든 지형 Collider2D를 One-Way Platform으로 자동 변환. + /// 위에서만 착지·측면·아래 통과. Player·Enemy·DeathZone·VictoryZone·TokenInstance·Trigger Collider 영역 제외. /// [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] static void SetupOneWayPlatforms() { - var tilemapColliders = Object.FindObjectsByType(FindObjectsSortMode.None); - foreach (var c in tilemapColliders) + int applied = 0; + var allColliders = Object.FindObjectsByType(FindObjectsSortMode.None); + foreach (var c in allColliders) { + if (c == null) continue; + if (c.isTrigger) continue; + // Player·Enemy·기타 GameObject 영역 제외 + if (c.GetComponent() != null) continue; + if (c.GetComponent() != null) continue; + if (c.GetComponent() != null) continue; + if (c.GetComponent() != null) continue; + if (c.GetComponent() != null) continue; + if (c.GetComponent() != null) continue; + c.usedByEffector = true; var effector = c.GetComponent(); if (effector == null) effector = c.gameObject.AddComponent(); @@ -35,7 +46,9 @@ namespace Platformer.Mechanics effector.rotationalOffset = 0f; effector.useSideFriction = false; effector.useSideBounce = false; + applied++; } + Debug.Log($"[BT19-OneWay] applied={applied} totalColliders={allColliders.Length}"); } } } diff --git a/Assets/Scripts/Mechanics/Health.cs b/Assets/Scripts/Mechanics/Health.cs index ae89918..f33c43f 100644 --- a/Assets/Scripts/Mechanics/Health.cs +++ b/Assets/Scripts/Mechanics/Health.cs @@ -188,6 +188,33 @@ namespace Platformer.Mechanics /// SOT: 캐릭터_리소스_규칙_v1.md §3.1.4 death → resurrection 시퀀스. /// BT7-Plan 영역: 부활 시 maxHP 회복 룰 — 현재 전체 회복, 향후 부분 회복 룰 결정 시 Resurrect(int) 오버로드 추가. /// + /// + /// 시스템 페널티 영역 — hit Animator 영역 발동 X 영역 단순 HP 감소. 낙사 복귀 영역·환경 데미지 영역 등. + /// PD 지시 2026-05-07 — 낭떠러지 복귀 시 hit 모션 재생 X. + /// + public void DecrementSilent(int damage) + { + if (damage <= 0) return; + if (Time.time < invulnerableUntil) return; + + currentHP = Mathf.Clamp(currentHP - damage, 0, maxHP); + if (invulnerableDuration > 0f) invulnerableUntil = Time.time + invulnerableDuration; + + if (currentHP > 0) + { + // hit Animator Trigger 영역 X (영역 핵심 차이) — OnDamagedEvent만 발화 + OnDamagedEvent?.Invoke(damage); + } + if (currentHP == 0) + { + var animator = GetComponent(); + if (animator != null) animator.SetBool("dead", true); + OnDeathEvent?.Invoke(); + var ev = Schedule(); + ev.health = this; + } + } + /// /// 외부 시스템이 임시 무적 시간을 부여 (낙사 위치 복귀·체크포인트 등). 기존 i-frame과 비교해 더 긴 시간을 채택. /// PD 지시 2026-05-07 — 낙사 시 1초 무적.