From 0eea12d94580752d9ceb19d86ebf62c558561a1d Mon Sep 17 00:00:00 2001 From: swrring Date: Thu, 7 May 2026 17:26:45 +0900 Subject: [PATCH] =?UTF-8?q?BT5-Dev=20#31:=20Level=20Tilemap=20Layer=208=20?= =?UTF-8?q?=EB=B3=80=ED=99=98=20+=20Raycast=20=EB=8F=99=EC=A0=81=20?= =?UTF-8?q?=EA=B1=B0=EB=A6=AC=C2=B7Start=20=EC=A6=89=EC=8B=9C=20=ED=99=9C?= =?UTF-8?q?=EC=84=B1=20(=EC=B6=A9=EB=8F=8C=20=EC=A7=84=EB=8B=A8=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [BT30-Collide] name='Level' layer=0 — Player 충돌 GameObject = Level Tilemap 확정. PD 의도 = Level Tilemap 영역 전체 Drop-Through (점프 시 통과 + 하강 시 Raycast 착지) 본 PM 자인 (BT28 떨어짐 원인): - Raycast 거리 0.1m 너무 짧음 → velocity 빠른 하강 시 miss - 시작 시 즉시 활성 X → Player 시작 위치 발판 영역 통과 = 떨어짐 정정: - GameOptimizer: TilemapCollider2D 제외 영역 폐기 → Level Tilemap도 Layer 8 변환 - PlatformDropThrough.Start: 시작 시 즉시 1회 raycast → Player 시작 위치 발판 영역 충돌 활성 (떨어짐 차단) - PlatformDropThrough.Update: footRayDistance 0.1 → 0.5 + velocity 기반 동적 거리 (Mathf.Max + |vy|*deltaTime + 0.1) 동작: - 시작 시 [BT31-StartHit] 출력 + Player 발판 위 정상 정착 - 점프 시 IgnoreCollision(true) 복구 = 통과 - 하강 시 raycast hit → IgnoreCollision(false) = 착지 --- Assets/Scripts/Mechanics/GameOptimizer.cs | 29 ++++--------------- .../Scripts/Mechanics/PlatformDropThrough.cs | 23 ++++++++++++--- 2 files changed, 24 insertions(+), 28 deletions(-) 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; // 점프 상승