BT5-Dev #29: 일반 지면 Layer 0 복원 + Foreground TilemapCollider2D 동적 추가 (PM 자인)

PD 보고: 게임 시작 시 Player 바닥으로 계속 떨어짐 — '점프 후 착지는 가능해야 한다고 했잖아'

본 PM 자인 (BT28 잘못):
- 모든 Collider(TilemapCollider2D 포함) Layer 8 변환 = 일반 지면도 Layer 8 = 통과 = 떨어짐
- 표준 platformer 영역 = 일반 지면(Layer 0) + 발판(Layer 8) 분리 의무

정정:
- TilemapCollider2D 제외 영역 복원 → Level Tilemap = Layer 0 = 일반 충돌 = 착지 정합
- Foreground GameObject(TilemapRenderer만·Collider 미부착) 영역에 TilemapCollider2D 동적 추가 + Layer 8 변환 → 발판 정합

동작:
- Level Tilemap = 일반 지면 (Layer 0) = Player 정상 착지·이동
- Foreground Tilemap = 발판 (Layer 8) = 기본 통과 + Player 발 Raycast 시 Drop-Through 착지
- 별개 BoxCollider2D(Alien 등) = Layer 8 = 발판 정합
This commit is contained in:
깃 관리자 2026-05-07 17:15:57 +09:00
parent ebab78c4b1
commit 4fd9369139
1 changed files with 24 additions and 7 deletions

View File

@ -31,8 +31,8 @@ namespace Platformer.Mechanics
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
static void SetupJumpThroughPlatforms() static void SetupJumpThroughPlatforms()
{ {
// BT5-Dev #28 — Tilemap 영역 포함 모든 일반 Collider Layer 8 변환. // BT5-Dev #29 — 일반 지면 Tilemap 일반 충돌 복원 + Foreground 발판만 Layer 8.
// Drop-Through 표준 패턴 = 모든 발판·지면이 Layer 8. PlatformDropThrough Raycast가 하강 시 충돌 활성 = 착지. // 일반 지면(Level TilemapCollider2D) = Layer 0 = 착지 정합 / 발판(Foreground·별개 BoxCollider) = Layer 8 = Drop-Through
int applied = 0, excluded = 0; int applied = 0, excluded = 0;
var allColliders = Object.FindObjectsByType<Collider2D>(FindObjectsSortMode.None); var allColliders = Object.FindObjectsByType<Collider2D>(FindObjectsSortMode.None);
var appliedNames = new System.Collections.Generic.List<string>(); var appliedNames = new System.Collections.Generic.List<string>();
@ -40,6 +40,8 @@ namespace Platformer.Mechanics
{ {
if (c == null) continue; if (c == null) continue;
if (c.isTrigger) { excluded++; continue; } if (c.isTrigger) { excluded++; continue; }
// 일반 지면 Tilemap 제외 (Layer 0 정상 충돌)
if (c.GetComponent<UnityEngine.Tilemaps.TilemapCollider2D>() != null) { excluded++; continue; }
if (c.GetComponent<PlayerController>() != null if (c.GetComponent<PlayerController>() != null
|| c.GetComponent<EnemyController>() != null || c.GetComponent<EnemyController>() != null
|| c.GetComponent<DeathZone>() != null || c.GetComponent<DeathZone>() != null
@ -51,18 +53,33 @@ namespace Platformer.Mechanics
continue; continue;
} }
// PlatformEffector2D 잔존 제거 (BT25 누적 영향 차단)
var effector = c.GetComponent<PlatformEffector2D>(); var effector = c.GetComponent<PlatformEffector2D>();
if (effector != null) Object.Destroy(effector); if (effector != null) Object.Destroy(effector);
c.usedByEffector = false; c.usedByEffector = false;
// Layer 8 변환 → IgnoreLayerCollision 기본 통과 + PlatformDropThrough Raycast 착지
c.gameObject.layer = 8; c.gameObject.layer = 8;
applied++; applied++;
if (appliedNames.Count < 8) appliedNames.Add($"{c.gameObject.name}({c.GetType().Name})"); if (appliedNames.Count < 8) appliedNames.Add($"{c.gameObject.name}({c.GetType().Name})");
} }
Debug.Log($"[BT28-JumpThrough] applied={applied} excluded={excluded} total={allColliders.Length}");
Debug.Log($"[BT28-JumpThrough] appliedSamples=[{string.Join(", ", appliedNames)}]"); // BT29 — Foreground GameObject(TilemapRenderer만 부착·Collider 미부착)에 TilemapCollider2D 동적 추가 + Layer 8
var foreground = GameObject.Find("Foreground");
if (foreground != null)
{
var fgTc = foreground.GetComponent<UnityEngine.Tilemaps.TilemapCollider2D>();
if (fgTc == null)
{
fgTc = foreground.AddComponent<UnityEngine.Tilemaps.TilemapCollider2D>();
}
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)}]");
} }
} }
} }