2026-05-20 무기습득

This commit is contained in:
2026-05-20 10:57:44 +09:00
parent 4a0b07701e
commit 3769ff87bf
289 changed files with 19793 additions and 14 deletions

View File

@@ -120,6 +120,11 @@ public class PlayerController : MonoBehaviour,IDamageable
private Animator _anim;
private SpriteRenderer _spriteRenderer; // 좌우 반전 + flipX 페이싱용
// ─── 무기 시스템 ────────────────────────────────────────────────────
// PlayerWeaponInventory가 현재 장착 무기 관리. 무기 교체 시 OnWeaponChanged 이벤트 발화.
// 무장 시 idle/walk 애니메이션과 Punch 콤보 root가 무기 데이터로 교체됨.
private PlayerWeaponInventory _weaponInventory;
// 컴포넌트 캐싱 + 자식 AttackHitbox 자동 보장 + hit 이벤트 구독.
private void Awake()
{
@@ -130,6 +135,12 @@ private void Awake()
EnsureAttackHitbox();
// 공격이 enemy를 hit하면 _lastHitEnemy를 기억 → 다음 잡기에서 그 enemy를 우선 타겟팅.
_attackHitbox.OnHit += OnAttackHit;
// 무기 인벤토리: 같은 GameObject에 컴포넌트가 없으면 자동 부착.
_weaponInventory = GetComponent<PlayerWeaponInventory>();
if (_weaponInventory == null)
_weaponInventory = gameObject.AddComponent<PlayerWeaponInventory>();
_weaponInventory.OnWeaponChanged += OnWeaponChanged;
}
private void ResolveBodyColliderReference()
@@ -159,6 +170,9 @@ private void Start()
InputManager.Instance.OnRoll_Event += OnRollInput;
InputManager.Instance.OnBackDash_Event += OnBackDashInput;
InputManager.Instance.OnGrabSmash_Event += OnGrabSmashInput;
InputManager.Instance.OnWeaponSlot1_Event += OnWeaponSlot1Input;
InputManager.Instance.OnWeaponSlot2_Event += OnWeaponSlot2Input;
InputManager.Instance.OnWeaponSlot3_Event += OnWeaponSlot3Input;
}
// 이벤트 구독 해제 + 진행 중인 async 작업 모두 취소.
@@ -175,6 +189,9 @@ private void OnDestroy()
InputManager.Instance.OnRoll_Event -= OnRollInput;
InputManager.Instance.OnBackDash_Event -= OnBackDashInput;
InputManager.Instance.OnGrabSmash_Event -= OnGrabSmashInput;
InputManager.Instance.OnWeaponSlot1_Event -= OnWeaponSlot1Input;
InputManager.Instance.OnWeaponSlot2_Event -= OnWeaponSlot2Input;
InputManager.Instance.OnWeaponSlot3_Event -= OnWeaponSlot3Input;
}
CancelAndDispose(ref _attackCts);
@@ -184,6 +201,25 @@ private void OnDestroy()
if (_attackHitbox != null)
_attackHitbox.OnHit -= OnAttackHit;
if (_weaponInventory != null)
_weaponInventory.OnWeaponChanged -= OnWeaponChanged;
}
// ─── 무기 슬롯 입력 핸들러 ───────────────────────────────────────────
// Key 1 → 맨손, Key 2 → 첫 픽업 무기, Key 3 → 두 번째 픽업 무기.
private void OnWeaponSlot1Input() => _weaponInventory.EquipUnarmed();
private void OnWeaponSlot2Input() => _weaponInventory.EquipSlot(0);
private void OnWeaponSlot3Input() => _weaponInventory.EquipSlot(1);
// 무기 교체 이벤트 콜백.
// 콤보 상태를 리셋하고 locomotion 애니메이션을 즉시 갱신.
private void OnWeaponChanged(WeaponData weapon)
{
_currentNode = null;
_comboWindowTimer = 0f;
_pendingInput = null;
_activeBaseState = null; // 강제 재평가
PlayLocomotionState();
}
// 매 물리 프레임의 메인 흐름:
@@ -346,9 +382,10 @@ private void ExecuteComboInput(ComboInputType input)
}
// 이어갈 연계가 없으면 입력에 맞는 루트 노드부터 새로 시작한다.
// Punch 입력은 무기 장착 시 무기의 AttackRootNode로 분기 (맨손이면 기본 _punchRootNode).
ComboNode root = input switch
{
ComboInputType.Punch => _punchRootNode,
ComboInputType.Punch => GetPunchRootNode(),
ComboInputType.Kick => _kickRootNode,
ComboInputType.Grab => _grabSmashRootNode,
_ => null
@@ -361,6 +398,15 @@ private void ExecuteComboInput(ComboInputType input)
_comboWindowTimer = root.ComboWindow;
}
// 무장 시 무기 데이터의 AttackRootNode 사용 (비어있으면 기본 _punchRootNode 폴백).
private ComboNode GetPunchRootNode()
{
WeaponData equipped = _weaponInventory != null ? _weaponInventory.CurrentWeapon : null;
if (equipped != null && equipped.AttackRootNode != null)
return equipped.AttackRootNode;
return _punchRootNode;
}
private bool CanPerformAction(ActionData data)
{
if (data == null) return false;
@@ -889,10 +935,19 @@ private string ChooseLocomotionState()
return _jumpMidAnimationState;
}
if (_moveInputX != 0f && !string.IsNullOrEmpty(_walkAnimationState))
return _walkAnimationState;
// 무기 장착 시 무기 데이터의 idle/walk를 우선 사용 (비어있으면 기본값으로 폴백).
WeaponData equipped = _weaponInventory != null ? _weaponInventory.CurrentWeapon : null;
string walk = equipped != null && !string.IsNullOrEmpty(equipped.WalkAnimationState)
? equipped.WalkAnimationState
: _walkAnimationState;
string idle = equipped != null && !string.IsNullOrEmpty(equipped.IdleAnimationState)
? equipped.IdleAnimationState
: _idleAnimationState;
return _idleAnimationState;
if (_moveInputX != 0f && !string.IsNullOrEmpty(walk))
return walk;
return idle;
}
private void UpdateLocomotionAnimation()