BT5-Dev #34: Layer 8·Raycast 폐기 + PlatformEffector2D 표준 OneWay 복원 (PM 자인)

진단:
- [BT32-StartHit] dist=0.54 layer=8 정상 + Player 떨어짐 모순
- 원인: Physics2D.IgnoreLayerCollision(13, 8, true) Layer Matrix OFF + Physics2D.IgnoreCollision(c1, c2, false) 호출 충돌
- Unity Manual: Layer Matrix 영역 OFF면 개별 IgnoreCollision(false) 호출 무시
- 본 PM 영역 잘못: Layer 8 + Raycast 영역 표준 패턴 X

진정한 표준: PlatformEffector2D + useOneWay + surfaceArc 180
- 위에서 떨어지면 충돌(착지)
- 옆·아래·점프 상승 시 통과
- Layer 무관 (기본 Layer 0)

정정:
- IgnoreLayerCollision(13, 8) 폐기 (Layer 13 ↔ 14만 유지)
- 모든 일반 Collider(Tilemap 포함) PlatformEffector2D + useOneWay 적용
- Layer 8 잔존 → Layer 0 복원
- PlayerController PlatformDropThrough AddComponent → Destroy 대체
- PlatformDropThrough.cs 영역 동작 X (자동 제거)
This commit is contained in:
깃 관리자 2026-05-07 17:49:58 +09:00
parent 0e56408e17
commit cd60c71097
2 changed files with 22 additions and 14 deletions

View File

@ -16,11 +16,10 @@ namespace Platformer.Mechanics
QualitySettings.vSyncCount = 0;
Time.fixedDeltaTime = 1f / 60f;
// BT5-Dev #22 — Player(13) ↔ Enemy(14) 충돌 영구 OFF
// BT5-Dev #34 — Layer Matrix 영역 = Player(13) ↔ Enemy(14)만 OFF. JumpThrough Layer 8 영역 폐기.
// OneWay = PlatformEffector2D 영역 표준 패턴 활용 (Layer Matrix 폐기)
Physics2D.IgnoreLayerCollision(13, 14, true);
// BT5-Dev #27 — Player(13) ↔ JumpThrough(8) 충돌 기본 OFF (Raycast 시점만 동적 활성)
Physics2D.IgnoreLayerCollision(13, 8, true);
Debug.Log($"[BT27-LayerSep] Player(13) ↔ Enemy(14)·JumpThrough(8) collision OFF");
Debug.Log($"[BT34-LayerSep] Player(13) ↔ Enemy(14) collision OFF (Layer 8 영역 폐기·PlatformEffector2D 영역 활용)");
}
/// <summary>
@ -31,9 +30,9 @@ namespace Platformer.Mechanics
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
static void SetupJumpThroughPlatforms()
{
// BT5-Dev #31 — [BT30-Collide] 진단 결과: Player 충돌 GameObject = 'Level'(Tilemap, Layer 0).
// PD 의도 = Level Tilemap 영역 전체 Drop-Through (점프 시 통과 + 하강 시 Raycast로 착지).
// 모든 Collider Layer 8 변환 (Tilemap 포함). PlatformDropThrough Raycast 거리 충분히 크게 + Start 즉시 활성.
// BT5-Dev #34 — Unity 표준 OneWay Platform = PlatformEffector2D + useOneWay + surfaceArc 180.
// 모든 일반 Collider(Tilemap 포함) PlatformEffector2D 적용. Layer 영역 무관 (기본 Layer 0 유지).
// 동작: 위에서 떨어지면 충돌(착지) / 옆·아래·점프 상승 시 통과
int applied = 0, excluded = 0;
var allColliders = Object.FindObjectsByType<Collider2D>(FindObjectsSortMode.None);
var appliedNames = new System.Collections.Generic.List<string>();
@ -52,15 +51,23 @@ namespace Platformer.Mechanics
continue;
}
// BT34 — Layer 8 변환 폐기 (Layer 0 유지) + PlatformEffector2D 영역 OneWay 적용
// BT31 영역 잔존 Layer 8 영역 → Layer 0 복원
if (c.gameObject.layer == 8) c.gameObject.layer = 0;
c.usedByEffector = true;
var effector = c.GetComponent<PlatformEffector2D>();
if (effector != null) Object.Destroy(effector);
c.usedByEffector = false;
c.gameObject.layer = 8;
if (effector == null) effector = c.gameObject.AddComponent<PlatformEffector2D>();
effector.useOneWay = true;
effector.surfaceArc = 180f;
effector.rotationalOffset = 0f;
effector.useSideFriction = false;
effector.useSideBounce = false;
applied++;
if (appliedNames.Count < 8) appliedNames.Add($"{c.gameObject.name}({c.GetType().Name})");
}
Debug.Log($"[BT31-JumpThrough] applied={applied} excluded={excluded} total={allColliders.Length}");
Debug.Log($"[BT31-JumpThrough] appliedSamples=[{string.Join(", ", appliedNames)}]");
Debug.Log($"[BT34-OneWay] applied={applied} excluded={excluded} total={allColliders.Length}");
Debug.Log($"[BT34-OneWay] appliedSamples=[{string.Join(", ", appliedNames)}]");
}
}
}

View File

@ -82,8 +82,9 @@ namespace Platformer.Mechanics
// PD 지시 2026-05-07 — 동반 컴포넌트 자동 부착 (Inspector 부착 불요)
if (GetComponent<PlayerInvulnerabilityFlash>() == null) gameObject.AddComponent<PlayerInvulnerabilityFlash>();
if (GetComponent<Platformer.UI.ResurrectPromptUI>() == null) gameObject.AddComponent<Platformer.UI.ResurrectPromptUI>();
// BT5-Dev #27 — Layer 8 발판 동적 충돌 (PD 제안 Raycast 방식)
if (GetComponent<PlatformDropThrough>() == null) gameObject.AddComponent<PlatformDropThrough>();
// BT5-Dev #34 — PlatformDropThrough 폐기 (PlatformEffector2D 표준 패턴 활용)
var oldDrop = GetComponent<PlatformDropThrough>();
if (oldDrop != null) Destroy(oldDrop);
// PD 지시 2026-05-07 — 사망 시 입력 차단 / 부활 시 입력 복원
if (health != null)