BT5-Dev #69: Down + Jump Drop-Through 입력 추가 (PD 명시 채택)

PD 명시 (2026-05-08): "발판과 같이 아래가 뚫려있고 이동 가능한 영역이 있는 경우, 아래 방향키 상태로 점프하면 점프 모션과 함께 내려올 수 있도록"

표준 platformer 패턴 (Drop-Through Input):
- Player가 발판(Layer 16) 위 + Down 방향키 + Jump 키 동시 입력
- = Layer 16 mask 강제 OFF (DROP_THROUGH_DURATION=0.3초) → 발판 통과
- = velocity.y = 0 (위 점프 X·gravity로 자연 낙하)
- = jumpState = PrepareToJump (점프 애니메이션 발동·시각상 점프 모션)

변경 (PlayerController.cs 3영역):
1. 클래스 변수 추가:
   - float dropThroughTimer (Layer 16 mask 강제 OFF 지속 시간)
   - const float DROP_THROUGH_DURATION = 0.3f
   - bool dropThroughJump (본 frame Drop-Through 점프 발동 분기)

2. Update 영역:
   - Move Input 영역 y < -0.5 (Down) + Jump WasPressed → dropThroughTimer 활성 + dropThroughJump=true
   - 매 frame dropThroughTimer 감소 (Time.deltaTime)

3. UpdateContactFilterForDropThrough 영역:
   - isJumpingThrough 조건에 dropThroughTimer > 0 추가
   - Drop-Through 활성 시 Layer 16 mask 강제 OFF

4. ComputeVelocity 영역:
   - jump && IsGrounded 시 dropThroughJump 분기:
     - dropThroughJump → velocity.y = 0 (위 점프 X)
     - else → velocity.y = jumpTakeOffSpeed (기존 정상 점프)

효과 (PD 의도 정합):
- 일반 점프 (Jump only) = 위로 점프 (그대로)
- Drop-Through (Down + Jump) = 발판 통과 + 점프 모션 + 자연 낙하
- 0.3초 후 mask 자동 복원 (다른 발판 위 정상 착지 가능)

후속 의무:
- PD Refresh+Play 시각 검증 (발판 위 + Down + Jump → 통과·낙하 + 점프 애니메이션)
- 정합 시 BT49~BT65 영구 폐기 + R2 + BT68 + BT69 영역 영구 채택
This commit is contained in:
깃 관리자 2026-05-08 00:26:12 +09:00
parent c9b39c4373
commit 643d1ae9a0
1 changed files with 32 additions and 3 deletions

View File

@ -41,6 +41,11 @@ namespace Platformer.Mechanics
public JumpState jumpState = JumpState.Grounded; public JumpState jumpState = JumpState.Grounded;
private bool stopJump; private bool stopJump;
// BT69 — Down + Jump Drop-Through (PD 명시 2026-05-08): Down 누른 상태에서 점프 시 발판 통과 + 점프 모션
private float dropThroughTimer = 0f; // 활성 시간 동안 Layer 16 mask 강제 OFF
private const float DROP_THROUGH_DURATION = 0.3f; // Drop-Through 활성 지속 시간 (초)
private bool dropThroughJump = false; // 본 frame Drop-Through 점프 발동 여부 (velocity.y 처리 분기)
/*internal new*/ public Collider2D collider2d; /*internal new*/ public Collider2D collider2d;
/*internal new*/ public AudioSource audioSource; /*internal new*/ public AudioSource audioSource;
public Health health; public Health health;
@ -136,9 +141,19 @@ namespace Platformer.Mechanics
{ {
if (controlEnabled) if (controlEnabled)
{ {
move.x = m_MoveAction.ReadValue<Vector2>().x; Vector2 moveInput = m_MoveAction.ReadValue<Vector2>();
move.x = moveInput.x;
if (jumpState == JumpState.Grounded && m_JumpAction.WasPressedThisFrame()) if (jumpState == JumpState.Grounded && m_JumpAction.WasPressedThisFrame())
{
// BT69 — Down + Jump = Drop-Through (PD 명시 2026-05-08)
bool downHeld = moveInput.y < -0.5f;
if (downHeld)
{
dropThroughTimer = DROP_THROUGH_DURATION;
dropThroughJump = true;
}
jumpState = JumpState.PrepareToJump; jumpState = JumpState.PrepareToJump;
}
else if (m_JumpAction.WasReleasedThisFrame()) else if (m_JumpAction.WasReleasedThisFrame())
{ {
stopJump = true; stopJump = true;
@ -150,6 +165,9 @@ namespace Platformer.Mechanics
{ {
move.x = 0; move.x = 0;
} }
// BT69 — Drop-Through Timer 감소 (Layer 16 mask 강제 OFF 지속 시간)
if (dropThroughTimer > 0f) dropThroughTimer -= Time.deltaTime;
UpdateJumpState(); UpdateJumpState();
base.Update(); base.Update();
@ -205,8 +223,10 @@ namespace Platformer.Mechanics
int baseMask = Physics2D.GetLayerCollisionMask(gameObject.layer); int baseMask = Physics2D.GetLayerCollisionMask(gameObject.layer);
// BT5-Dev #43 — IsGrounded 영역 폐기 (frame 0 미설정 → 떨어짐). footHit 단독 + 점프 영역 OFF 강제 // BT5-Dev #43 — IsGrounded 영역 폐기 (frame 0 미설정 → 떨어짐). footHit 단독 + 점프 영역 OFF 강제
// BT69 — Drop-Through Timer 활성 시 Layer 16 mask 강제 OFF (Down + Jump 입력 발판 통과)
bool isJumpingThrough = jumpState == JumpState.Jumping bool isJumpingThrough = jumpState == JumpState.Jumping
|| (jumpState == JumpState.InFlight && velocity.y > 0.01f); || (jumpState == JumpState.InFlight && velocity.y > 0.01f)
|| dropThroughTimer > 0f;
bool standingOnPlatform = false; bool standingOnPlatform = false;
if (collider2d != null && !isJumpingThrough) if (collider2d != null && !isJumpingThrough)
@ -226,8 +246,17 @@ namespace Platformer.Mechanics
protected override void ComputeVelocity() protected override void ComputeVelocity()
{ {
if (jump && IsGrounded) if (jump && IsGrounded)
{
// BT69 — Drop-Through 점프 분기: Down + Jump 입력 시 위로 점프 X (gravity로 떨어짐 + 점프 모션만 유지)
if (dropThroughJump)
{
velocity.y = 0f; // 위 속도 X — 발판 통과 후 자연 낙하
dropThroughJump = false;
}
else
{ {
velocity.y = jumpTakeOffSpeed * model.jumpModifier; velocity.y = jumpTakeOffSpeed * model.jumpModifier;
}
jump = false; jump = false;
} }
else if (stopJump) else if (stopJump)