BT5-Dev #25: Bounds 기반 footHeadDelta + Tilemap OneWay 폐기 (PD 의도 정합)
PD 보고: 1. 점프 밟기 위치 너무 높음 — dyAtCollision = transform 차 (center vs center) 영역 잘못 2. 발판 통과 X — Tilemap OneWay 영역 적용 = 모든 Tile 영역 OneWay = 일반 지면 영역 깨짐 정정: - EnemyController.Update: dyAtCollision = Player.Bounds.min.y - Enemy.VisualBounds.max.y (footHeadDelta) - PlayerEnemyCollision: stomped = (-0.2 < delta < 0.3) — Player 발 ≈ Enemy 머리 영역 - GameOptimizer: TilemapCollider2D 영역 영역 OneWay 영역 영역 폐기 → 별개 BoxCollider2D 영역 OneWay (Alien 등 점프 가능 발판 영역 영역만)
This commit is contained in:
parent
d4e8708f42
commit
d15a46b5cc
|
|
@ -21,9 +21,12 @@ namespace Platformer.Gameplay
|
|||
/// <summary>BT5-Dev #16 — EnemyController.Update에서 측정한 Player·Enemy y 차 (밟기 판정 영역).</summary>
|
||||
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<PlatformerModel>();
|
||||
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<PlayerEnemyCollision>();
|
||||
ev.player = _cachedPlayer;
|
||||
ev.enemy = this;
|
||||
ev.dyAtCollision = dy;
|
||||
ev.dyAtCollision = footHeadDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Collider2D>(FindObjectsSortMode.None);
|
||||
var appliedNames = new System.Collections.Generic.List<string>();
|
||||
var excludedNames = new System.Collections.Generic.List<string>();
|
||||
foreach (var c in allColliders)
|
||||
{
|
||||
if (c == null) continue;
|
||||
if (c.isTrigger) { excludedTrigger++; continue; }
|
||||
if (c.GetComponent<UnityEngine.Tilemaps.TilemapCollider2D>() != null) { excludedTilemap++; continue; } // BT25 — Tilemap 영역 영역 영역 일반 충돌 영역
|
||||
if (c.GetComponent<PlayerController>() != null
|
||||
|| c.GetComponent<EnemyController>() != null
|
||||
|| c.GetComponent<DeathZone>() != 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)}]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue