diff --git a/Assets/Scripts/Gameplay/PlayerEnemyCollision.cs b/Assets/Scripts/Gameplay/PlayerEnemyCollision.cs
index 59a5997..7959412 100644
--- a/Assets/Scripts/Gameplay/PlayerEnemyCollision.cs
+++ b/Assets/Scripts/Gameplay/PlayerEnemyCollision.cs
@@ -21,9 +21,12 @@ namespace Platformer.Gameplay
/// BT5-Dev #16 — EnemyController.Update에서 측정한 Player·Enemy y 차 (밟기 판정 영역).
public float dyAtCollision;
- // BT5-Dev #24 — 실측 (Editor.log): 점프 정점 dy 최댓값 0.95. STOMP_MIN_DY 1.0은 도달 X = stomped 영원히 X.
- // 0.7 = dy 0.95 영역에서 영역 발동 + 측면 dy 0.15 영역에서 발동 X (정합)
- const float STOMP_MIN_DY = 0.7f;
+ // BT5-Dev #25 — dyAtCollision 영역 = footHeadDelta (Player 발 - Enemy 머리)
+ // 0 = 닿음 / 양수 = Player 발이 Enemy 머리 위 / 음수 = Player 발이 Enemy 머리 영역 안 영역
+ // 측면 충돌 시 footHeadDelta 음수 (Player 발 영역 < Enemy 머리 영역)
+ // 점프 밟기 시 footHeadDelta -0.2 ~ +0.3 영역 (착지 직전·직후)
+ const float STOMP_DELTA_MIN = -0.2f; // Enemy 머리 영역 영역 영역 영역 영역 영역 영역
+ const float STOMP_DELTA_MAX = 0.3f; // Enemy 머리 영역 영역 영역 영역 영역 영역 영역
PlatformerModel model = Simulation.GetModel();
@@ -31,11 +34,10 @@ namespace Platformer.Gameplay
{
if (player == null || player.health == null || enemy == null) return;
- // BT5-Dev #21 — 밟기 영역: Player 발이 Enemy 영역 위 (체공 상승·하강 모두 영역 — vy 조건 폐기)
- // dy > STOMP_MIN_DY 영역에서 점프 영역 보장됨 (측면 닿음 영역 dy ≈ 0). vy<0 조건은 상승 시점 측면 피격 오인 발동
- bool stomped = dyAtCollision > STOMP_MIN_DY;
+ // BT5-Dev #25 — Player 발이 Enemy 머리 영역 영역 영역 영역 발동 (footHeadDelta 영역 영역 영역 영역)
+ bool stomped = dyAtCollision > STOMP_DELTA_MIN && dyAtCollision < STOMP_DELTA_MAX;
- Debug.Log($"[PEC] stomped={stomped} dy={dyAtCollision:F2} vy={player.velocity.y:F2} (thr>{STOMP_MIN_DY}) pInvuln={player.health.IsInvulnerable}");
+ Debug.Log($"[PEC] stomped={stomped} delta={dyAtCollision:F2} (range {STOMP_DELTA_MIN}~{STOMP_DELTA_MAX}) pInvuln={player.health.IsInvulnerable}");
if (stomped)
{
diff --git a/Assets/Scripts/Mechanics/EnemyController.cs b/Assets/Scripts/Mechanics/EnemyController.cs
index 5e580d2..00e151b 100644
--- a/Assets/Scripts/Mechanics/EnemyController.cs
+++ b/Assets/Scripts/Mechanics/EnemyController.cs
@@ -108,18 +108,19 @@ namespace Platformer.Mechanics
}
if (_cachedPlayer != null && _cachedPlayer.health != null && _cachedPlayer.health.IsAlive)
{
- // BT5-Dev #16 — Distance 기반 단순 감지 (Bounds 영역 산수 영역 의존 X·항상 작동)
- // dx 0.7·|dy| 1.0 = 표준 platformer Enemy/Player 닿음 영역. dy > 0.5 = Player가 Enemy 위에서 밟음.
+ // BT5-Dev #25 — Bounds 기반 dy: Player 발 vs Enemy 머리 영역 (PD 의도 정합)
Vector3 ePos = transform.position;
Vector3 pPos = _cachedPlayer.transform.position;
float dx = Mathf.Abs(pPos.x - ePos.x);
- float dy = pPos.y - ePos.y;
+ float footY = _cachedPlayer.Bounds.min.y; // Player 발 world y
+ float headY = VisualBounds.max.y; // Enemy 머리 world y
+ float footHeadDelta = footY - headY; // 0 = 닿음 / 양수 = Player 발 위 / 음수 = Player 발 아래
- bool inRange = dx < hitRangeX && Mathf.Abs(dy) < hitRangeY;
+ bool inRange = dx < hitRangeX && Mathf.Abs(pPos.y - ePos.y) < hitRangeY;
if (inRange != _diagWasIntersecting)
{
- Debug.Log($"[EnemyDiag@{name}] inRange={inRange} dx={dx:F2} dy={dy:F2} (thresholds dx<{hitRangeX} |dy|<{hitRangeY}) | ePos={ePos} pPos={pPos}");
+ Debug.Log($"[EnemyDiag@{name}] inRange={inRange} footHeadDelta={footHeadDelta:F2} dx={dx:F2}");
_diagWasIntersecting = inRange;
}
@@ -128,7 +129,7 @@ namespace Platformer.Mechanics
var ev = Schedule();
ev.player = _cachedPlayer;
ev.enemy = this;
- ev.dyAtCollision = dy;
+ ev.dyAtCollision = footHeadDelta;
}
}
}
diff --git a/Assets/Scripts/Mechanics/GameOptimizer.cs b/Assets/Scripts/Mechanics/GameOptimizer.cs
index e03960f..30de1fb 100644
--- a/Assets/Scripts/Mechanics/GameOptimizer.cs
+++ b/Assets/Scripts/Mechanics/GameOptimizer.cs
@@ -29,15 +29,17 @@ namespace Platformer.Mechanics
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
static void SetupOneWayPlatforms()
{
+ // BT5-Dev #25 — Tilemap 영역 OneWay 영역 폐기 (모든 Tile 영역 OneWay = 일반 지면 영역도 영역 = 게임 영역 깨짐)
+ // 별개 BoxCollider2D 영역 영역 영역 영역 영역 영역 발판 영역 영역 OneWay 영역 영역 적용
int applied = 0;
- int excludedTrigger = 0, excludedActor = 0;
+ int excludedTrigger = 0, excludedActor = 0, excludedTilemap = 0;
var allColliders = Object.FindObjectsByType(FindObjectsSortMode.None);
var appliedNames = new System.Collections.Generic.List();
- var excludedNames = new System.Collections.Generic.List();
foreach (var c in allColliders)
{
if (c == null) continue;
if (c.isTrigger) { excludedTrigger++; continue; }
+ if (c.GetComponent() != null) { excludedTilemap++; continue; } // BT25 — Tilemap 영역 영역 영역 일반 충돌 영역
if (c.GetComponent() != null
|| c.GetComponent() != null
|| c.GetComponent() != null
@@ -60,8 +62,8 @@ namespace Platformer.Mechanics
applied++;
if (appliedNames.Count < 8) appliedNames.Add($"{c.gameObject.name}({c.GetType().Name})");
}
- Debug.Log($"[BT21-OneWay] applied={applied} trigger={excludedTrigger} actor={excludedActor} total={allColliders.Length}");
- Debug.Log($"[BT21-OneWay] appliedSamples=[{string.Join(", ", appliedNames)}]");
+ Debug.Log($"[BT25-OneWay] applied={applied} trigger={excludedTrigger} tilemap={excludedTilemap} actor={excludedActor} total={allColliders.Length}");
+ Debug.Log($"[BT25-OneWay] appliedSamples=[{string.Join(", ", appliedNames)}]");
}
}
}