diff --git a/Assets/Scripts/Mechanics/GameOptimizer.cs b/Assets/Scripts/Mechanics/GameOptimizer.cs index e4eac11..cc05d01 100644 --- a/Assets/Scripts/Mechanics/GameOptimizer.cs +++ b/Assets/Scripts/Mechanics/GameOptimizer.cs @@ -31,8 +31,9 @@ namespace Platformer.Mechanics [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] static void SetupJumpThroughPlatforms() { - // BT5-Dev #29 — 일반 지면 Tilemap 일반 충돌 복원 + Foreground 발판만 Layer 8. - // 일반 지면(Level TilemapCollider2D) = Layer 0 = 착지 정합 / 발판(Foreground·별개 BoxCollider) = Layer 8 = Drop-Through + // BT5-Dev #31 — [BT30-Collide] 진단 결과: Player 충돌 GameObject = 'Level'(Tilemap, Layer 0). + // PD 의도 = Level Tilemap 영역 전체 Drop-Through (점프 시 통과 + 하강 시 Raycast로 착지). + // 모든 Collider Layer 8 변환 (Tilemap 포함). PlatformDropThrough Raycast 거리 충분히 크게 + Start 즉시 활성. int applied = 0, excluded = 0; var allColliders = Object.FindObjectsByType(FindObjectsSortMode.None); var appliedNames = new System.Collections.Generic.List(); @@ -40,8 +41,6 @@ namespace Platformer.Mechanics { if (c == null) continue; if (c.isTrigger) { excluded++; continue; } - // 일반 지면 Tilemap 제외 (Layer 0 정상 충돌) - if (c.GetComponent() != null) { excluded++; continue; } if (c.GetComponent() != null || c.GetComponent() != null || c.GetComponent() != null @@ -60,26 +59,8 @@ namespace Platformer.Mechanics applied++; if (appliedNames.Count < 8) appliedNames.Add($"{c.gameObject.name}({c.GetType().Name})"); } - - // BT29 — Foreground GameObject(TilemapRenderer만 부착·Collider 미부착)에 TilemapCollider2D 동적 추가 + Layer 8 - var foreground = GameObject.Find("Foreground"); - if (foreground != null) - { - var fgTc = foreground.GetComponent(); - if (fgTc == null) - { - fgTc = foreground.AddComponent(); - } - foreground.layer = 8; - Debug.Log($"[BT29-Foreground] TilemapCollider2D added·Layer 8 applied to '{foreground.name}'"); - } - else - { - Debug.Log($"[BT29-Foreground] 'Foreground' GameObject not found"); - } - - Debug.Log($"[BT29-JumpThrough] applied={applied} excluded={excluded} total={allColliders.Length}"); - Debug.Log($"[BT29-JumpThrough] appliedSamples=[{string.Join(", ", appliedNames)}]"); + Debug.Log($"[BT31-JumpThrough] applied={applied} excluded={excluded} total={allColliders.Length}"); + Debug.Log($"[BT31-JumpThrough] appliedSamples=[{string.Join(", ", appliedNames)}]"); } } } diff --git a/Assets/Scripts/Mechanics/PlatformDropThrough.cs b/Assets/Scripts/Mechanics/PlatformDropThrough.cs index 34ae2e8..a63836f 100644 --- a/Assets/Scripts/Mechanics/PlatformDropThrough.cs +++ b/Assets/Scripts/Mechanics/PlatformDropThrough.cs @@ -13,8 +13,8 @@ namespace Platformer.Mechanics { const int JUMP_THROUGH_LAYER = 8; - [Tooltip("발 raycast 거리. 0.05~0.15 권장.")] - public float footRayDistance = 0.1f; + [Tooltip("발 raycast 기본 거리. velocity 영역에 따라 동적 확대.")] + public float footRayDistance = 0.5f; Collider2D _self; KinematicObject _ko; @@ -28,6 +28,20 @@ namespace Platformer.Mechanics _jumpThroughMask = 1 << JUMP_THROUGH_LAYER; } + void Start() + { + // BT5-Dev #31 — 게임 시작 시 즉시 raycast 1회 → Player 시작 위치가 발판 위면 즉시 충돌 활성 (떨어짐 차단) + if (_self == null) return; + Vector2 footPos = new Vector2(_self.bounds.center.x, _self.bounds.min.y + 0.02f); + RaycastHit2D startHit = Physics2D.Raycast(footPos, Vector2.down, footRayDistance, _jumpThroughMask); + if (startHit.collider != null) + { + Physics2D.IgnoreCollision(_self, startHit.collider, false); + _activePlatform = startHit.collider; + Debug.Log($"[BT31-StartHit] Player 시작 위치 발판 영역 충돌 활성: {startHit.collider.gameObject.name}"); + } + } + void Update() { if (_self == null || _ko == null) return; @@ -35,8 +49,9 @@ namespace Platformer.Mechanics // Player 발 위치 (collider 하단 중심) Vector2 footPos = new Vector2(_self.bounds.center.x, _self.bounds.min.y + 0.02f); - // Layer 8 발판 raycast (footRayDistance 영역만 검사) - RaycastHit2D hit = Physics2D.Raycast(footPos, Vector2.down, footRayDistance, _jumpThroughMask); + // velocity 기반 동적 거리 (빠른 하강 시 raycast miss 차단) + float dist = Mathf.Max(footRayDistance, Mathf.Abs(_ko.velocity.y) * Time.deltaTime + 0.1f); + RaycastHit2D hit = Physics2D.Raycast(footPos, Vector2.down, dist, _jumpThroughMask); bool falling = _ko.velocity.y <= 0.01f; // 하강 또는 정지 bool rising = _ko.velocity.y > 0.5f; // 점프 상승