BT5-Dev #46: prefab/Tile 영역 분리 (PD 제안 채택)

PD 진단: '접근 방법이 잘못 된 것 같아. 프리펩을 수정해야하는게 아닐까?'

진단:
- BT45 모든 Tilemap Layer 16 = 벽도 Drop-Through = 점프 시 벽 통과 (PD 보고 1)
- Foreground Tile asset m_ColliderType=None 가능성 → TilemapCollider2D 추가해도 Tile별 Collider 미생성 = 통과 X 영역 영역 (PD 보고 2)

정정:
- Level Tilemap (name='Level' + TilemapCollider2D) = Layer 0 (일반 지면·벽 영구 충돌)
- Foreground Tilemap = TilemapCollider2D + Layer 16 + 모든 Tile m_ColliderType=Sprite 런타임 강제 (HasTile 영역 영역 SetColliderType + ProcessTilemapChanges)
- Alien 등 별개 BoxCollider2D = Layer 16

동작:
- 시작 → Level Tilemap 위 정착 (Layer 0)
- 점프 영역 → 벽(Layer 0) 막힘 정합 / Foreground 발판(Layer 16) mask OFF 통과
- 걷기 옆 영역 발판 → footHit X → mask OFF → 통과
- 점프 후 발판 위 → footHit Layer 16 → standingOnPlatform=true → 착지
This commit is contained in:
깃 관리자 2026-05-07 18:37:43 +09:00
parent 1be657e215
commit 06c6d5b3c7
1 changed files with 37 additions and 8 deletions

View File

@ -30,8 +30,8 @@ namespace Platformer.Mechanics
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
static void SetupJumpThroughPlatforms()
{
// BT5-Dev #45 — Level Tilemap 영역 Layer 16 복원 (PD 의도: 점프 영역 통과·footHit 영역 영역 영역). Tilemap 단일 GameObject = 모든 Tile 동일 동작.
int applied = 0, excluded = 0;
// BT5-Dev #46 — PD 제안 채택: Level Tilemap = Layer 0 (일반 지면·벽 영구 충돌) / Foreground Tilemap = Layer 16 (공중 발판 Drop-Through·Tile m_ColliderType=Sprite 런타임 강제)
int applied = 0, excluded = 0, levelKept = 0;
var allColliders = Object.FindObjectsByType<Collider2D>(FindObjectsSortMode.None);
var appliedNames = new System.Collections.Generic.List<string>();
foreach (var c in allColliders)
@ -49,28 +49,57 @@ namespace Platformer.Mechanics
continue;
}
// BT46 — Level Tilemap (TilemapCollider2D + name='Level') = Layer 0 (일반 지면·벽 영구 충돌)
if (c.GetComponent<UnityEngine.Tilemaps.TilemapCollider2D>() != null && c.gameObject.name == "Level")
{
if (c.gameObject.layer == 16) c.gameObject.layer = 0; // 잔존 복원
var lvlEffector = c.GetComponent<PlatformEffector2D>();
if (lvlEffector != null) Object.Destroy(lvlEffector);
c.usedByEffector = false;
levelKept++;
continue;
}
var effector = c.GetComponent<PlatformEffector2D>();
if (effector != null) Object.Destroy(effector);
c.usedByEffector = false;
// BT5-Dev #45 — 모든 일반 Collider(Level Tilemap 포함) Layer 16 (PD 의도: 점프 영역 통과·footHit 영역 영역)
c.gameObject.layer = 16;
applied++;
if (appliedNames.Count < 8) appliedNames.Add($"{c.gameObject.name}({c.GetType().Name})");
}
// BT45 — Foreground 영역 미부착 시 TilemapCollider2D 동적 추가 + Layer 16
// BT46 — Foreground GameObject TilemapCollider2D + Layer 16 + 모든 Tile m_ColliderType=Sprite 런타임 강제
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 = 16;
Debug.Log($"[BT45-Foreground] TilemapCollider2D + Layer 16 applied to 'Foreground'");
var fgTilemap = foreground.GetComponent<UnityEngine.Tilemaps.Tilemap>();
if (fgTilemap != null)
{
var bounds = fgTilemap.cellBounds;
int forced = 0;
for (int x = bounds.xMin; x <= bounds.xMax; x++)
{
for (int y = bounds.yMin; y <= bounds.yMax; y++)
{
var pos = new Vector3Int(x, y, 0);
if (fgTilemap.HasTile(pos))
{
fgTilemap.SetColliderType(pos, UnityEngine.Tilemaps.Tile.ColliderType.Sprite);
forced++;
}
}
}
fgTc.ProcessTilemapChanges();
Debug.Log($"[BT46-Foreground] TilemapCollider2D + Layer 16 + ColliderType=Sprite forced on {forced} tiles");
}
}
Debug.Log($"[BT45-DropThrough] Layer16 applied={applied} excluded={excluded} total={allColliders.Length}");
Debug.Log($"[BT45-DropThrough] appliedSamples=[{string.Join(", ", appliedNames)}]");
Debug.Log($"[BT46-DropThrough] Layer16 applied={applied} levelKeptLayer0={levelKept} excluded={excluded} total={allColliders.Length}");
Debug.Log($"[BT46-DropThrough] appliedSamples=[{string.Join(", ", appliedNames)}]");
}
}
}