2026-05-20 공격방향전환
This commit is contained in:
@@ -36,8 +36,9 @@ public class ComboTransition
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 공격 방향. 방향키 입력에 따라 같은 노드라도 다른 액션을 낼 수 있다.
|
// 공격 방향. 방향키 입력에 따라 같은 노드라도 다른 액션을 낼 수 있다.
|
||||||
// Neutral = 방향키 없음(제자리) / Forward = 바라보는 방향 / Back = 반대 방향
|
// Neutral = 방향키 없음(제자리) / Up = 위 입력 / Down = 아래 입력
|
||||||
// Up = 위 입력 / Down = 아래 입력
|
// Forward = 좌우 입력 — 누른 쪽으로 페이싱을 돌린 뒤 공격하므로 항상 Forward.
|
||||||
|
// Back = 현재 입력 방식(좌우=전환)에서는 발생하지 않음. 직렬화 호환 위해 값 유지.
|
||||||
// 대각선 입력은 위/아래를 우선한다 (PlayerController.GetAttackDirection 참고).
|
// 대각선 입력은 위/아래를 우선한다 (PlayerController.GetAttackDirection 참고).
|
||||||
public enum AttackDirection
|
public enum AttackDirection
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -272,9 +272,16 @@ private void ExecuteBufferedInputIfReady()
|
|||||||
if (_attackCooldownTimer > 0f || !_pendingInput.HasValue) return;
|
if (_attackCooldownTimer > 0f || !_pendingInput.HasValue) return;
|
||||||
|
|
||||||
ComboInputType buffered = _pendingInput.Value;
|
ComboInputType buffered = _pendingInput.Value;
|
||||||
bool stillValid = Time.time - _pendingInputTime <= _bufferLifetime;
|
bool expired = Time.time - _pendingInputTime > _bufferLifetime;
|
||||||
|
|
||||||
|
// 진행 중인 공격을 "콤보 연계 없이" 캔슬하는 입력이면 아직 발화하지 않고,
|
||||||
|
// 그 공격이 끝날 때까지 버퍼에 남겨둔다 (마지막 공격 등이 캔슬되지 않게).
|
||||||
|
// 단, 수명이 지난 입력은 폐기.
|
||||||
|
if (!expired && _isAttackActive && !CanTransitionFromCurrentNode(buffered))
|
||||||
|
return;
|
||||||
|
|
||||||
_pendingInput = null;
|
_pendingInput = null;
|
||||||
if (stillValid)
|
if (!expired)
|
||||||
ExecuteComboInput(buffered);
|
ExecuteComboInput(buffered);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,10 +357,15 @@ private void OnGrabSmashInput()
|
|||||||
// 3) 그 외에는 즉시 ExecuteComboInput으로 발화
|
// 3) 그 외에는 즉시 ExecuteComboInput으로 발화
|
||||||
private void HandleComboInput(ComboInputType input)
|
private void HandleComboInput(ComboInputType input)
|
||||||
{
|
{
|
||||||
if (_isMotionActive && !CanTransitionFromCurrentNode(input))
|
// 콤보 연계(현재 노드의 트랜지션) 가능 여부 — 연계는 애니메이션 중에도 즉시 캔슬-체인.
|
||||||
|
bool canChain = CanTransitionFromCurrentNode(input);
|
||||||
|
|
||||||
|
if (_isMotionActive && !canChain)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_attackCooldownTimer > 0f)
|
// 쿨다운 중이거나, 진행 중인 공격을 "콤보 연계 없이" 끊으려는 입력이면 버퍼링.
|
||||||
|
// (마지막 공격처럼 다음 콤보가 없는 입력이 애니메이션을 캔슬하던 문제 방지)
|
||||||
|
if (_attackCooldownTimer > 0f || (_isAttackActive && !canChain))
|
||||||
{
|
{
|
||||||
float elapsed = Time.time - _attackStartTime;
|
float elapsed = Time.time - _attackStartTime;
|
||||||
// _bufferOpenTime 전엔 너무 일찍 누른 입력으로 간주하고 무시.
|
// _bufferOpenTime 전엔 너무 일찍 누른 입력으로 간주하고 무시.
|
||||||
@@ -370,6 +382,10 @@ private void HandleComboInput(ComboInputType input)
|
|||||||
|
|
||||||
private void ExecuteComboInput(ComboInputType input)
|
private void ExecuteComboInput(ComboInputType input)
|
||||||
{
|
{
|
||||||
|
// 좌우 방향키를 누르고 있으면 그쪽으로 페이싱 전환 후 공격.
|
||||||
|
// (콤보 중 facing이 잠겨 있어도 다음 콤보는 누른 방향으로 나간다.)
|
||||||
|
UpdateFacingFromMoveInput();
|
||||||
|
|
||||||
// 콤보 입력 가능 시간이 열려 있으면 현재 노드에서 다음 연계로 이어간다.
|
// 콤보 입력 가능 시간이 열려 있으면 현재 노드에서 다음 연계로 이어간다.
|
||||||
if (_comboWindowTimer > 0f && _currentNode != null)
|
if (_comboWindowTimer > 0f && _currentNode != null)
|
||||||
{
|
{
|
||||||
@@ -412,16 +428,14 @@ private void ExecuteComboInput(ComboInputType input)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 현재 방향키 입력을 공격 방향(AttackDirection)으로 변환.
|
// 현재 방향키 입력을 공격 방향(AttackDirection)으로 변환.
|
||||||
|
// 좌우 입력은 ExecuteComboInput에서 누른 쪽으로 페이싱을 돌리므로 항상 Forward.
|
||||||
// 대각선 입력은 위/아래를 우선한다 (점프 견제·다운 어택을 우선).
|
// 대각선 입력은 위/아래를 우선한다 (점프 견제·다운 어택을 우선).
|
||||||
// 좌우는 페이싱 기준으로 Forward(앞)/Back(뒤)로 구분.
|
|
||||||
private AttackDirection GetAttackDirection()
|
private AttackDirection GetAttackDirection()
|
||||||
{
|
{
|
||||||
if (_moveInputY > 0f) return AttackDirection.Up;
|
if (_moveInputY > 0f) return AttackDirection.Up;
|
||||||
if (_moveInputY < 0f) return AttackDirection.Down;
|
if (_moveInputY < 0f) return AttackDirection.Down;
|
||||||
if (_moveInputX == 0f) return AttackDirection.Neutral;
|
if (_moveInputX != 0f) return AttackDirection.Forward;
|
||||||
|
return AttackDirection.Neutral;
|
||||||
float facing = _spriteRenderer != null && _spriteRenderer.flipX ? -1f : 1f;
|
|
||||||
return Mathf.Sign(_moveInputX) == facing ? AttackDirection.Forward : AttackDirection.Back;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 노드의 방향별 변형 중 현재 입력 방향과 일치하는 액션을 선택.
|
// 노드의 방향별 변형 중 현재 입력 방향과 일치하는 액션을 선택.
|
||||||
|
|||||||
BIN
Assets/05_Data/Attack/SwordAttackA.asset
LFS
Normal file
BIN
Assets/05_Data/Attack/SwordAttackA.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Attack/SwordAttackA.asset.meta
Normal file
8
Assets/05_Data/Attack/SwordAttackA.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9568c042d8afb92489e171221fd3c5f1
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Attack/SwordAttackC.asset
LFS
Normal file
BIN
Assets/05_Data/Attack/SwordAttackC.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Attack/SwordAttackC.asset.meta
Normal file
8
Assets/05_Data/Attack/SwordAttackC.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 75f96bb80e3b29644b18bb27371a566e
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Attack/SwordAttackD.asset
LFS
Normal file
BIN
Assets/05_Data/Attack/SwordAttackD.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Attack/SwordAttackD.asset.meta
Normal file
8
Assets/05_Data/Attack/SwordAttackD.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 11114a385042cc144bb6e4acbe7a8e4e
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
BIN
Assets/05_Data/Combo/Combo_SwordAttackA.asset
LFS
Normal file
BIN
Assets/05_Data/Combo/Combo_SwordAttackA.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Combo/Combo_SwordAttackA.asset.meta
Normal file
8
Assets/05_Data/Combo/Combo_SwordAttackA.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b12b5c14d1123094dac17bd16ce49870
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
BIN
Assets/05_Data/Combo/Combo_SwordAttackC.asset
LFS
Normal file
BIN
Assets/05_Data/Combo/Combo_SwordAttackC.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Combo/Combo_SwordAttackC.asset.meta
Normal file
8
Assets/05_Data/Combo/Combo_SwordAttackC.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2c71093410e49d3448ccb17919f8120a
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Combo/Combo_SwordAttackD.asset
LFS
Normal file
BIN
Assets/05_Data/Combo/Combo_SwordAttackD.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Combo/Combo_SwordAttackD.asset.meta
Normal file
8
Assets/05_Data/Combo/Combo_SwordAttackD.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 92f806cd5d5db3c4cab5f5dd815b2620
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Reference in New Issue
Block a user