using UnityEngine; using System.Collections; public class PlayerAttack : MonoBehaviour { [Header("--- 참조 ---")] [SerializeField] private PlayerInteraction interaction; [SerializeField] private Stats stats; [SerializeField] private PlayerAnimator pAnim; [SerializeField] private PlayerHealth playerHealth; [SerializeField] private WeaponHitBox weaponHitBox; [Header("--- 설정 ---")] [SerializeField] private float attackCooldown = 0.4f; [SerializeField] private float fullChargeTime = 2f; [SerializeField] private float postComboDelay = 1.2f; // 막타 후 딜레이 (n초) private float _lastAttackTime, _chargeTimer; private bool _isCharging, _canAttack = true, _isAttacking = false; private int _comboCount = 0; // 콤보 카운트 public float ChargeProgress => Mathf.Clamp01(_chargeTimer / fullChargeTime); public bool IsCharging => _isCharging; // ⭐ 이동 스크립트에서 공격 중에 멈추게 할 때 사용하세요! public bool IsAttacking => _isAttacking; private void Update() { if (_isCharging) { _chargeTimer += Time.deltaTime; if (Input.GetMouseButtonDown(1)) { CancelCharging(); } } } public void PerformNormalAttack() { if (!_canAttack || (playerHealth != null && playerHealth.isHit)) return; if (interaction.CurrentWeapon == null || pAnim == null) return; if (Time.time < _lastAttackTime + attackCooldown) return; _isAttacking = true; // 🚫 공격 중 이동 제한 시작 _comboCount = (_comboCount % 3) + 1; // 1 -> 2 -> 3타 순환 pAnim.TriggerAttack(); _lastAttackTime = Time.time; } public void OnAttackShake() { if (CinemachineShake.Instance == null) return; if (_comboCount == 3) // 🔥 인왕 스타일 3타 막타 연출! { CinemachineShake.Instance.HitSlow(0.2f, 0.05f); // 묵직한 슬로우 CinemachineShake.Instance.CameraKick(10f); // 화끈한 카메라 킥 CinemachineShake.Instance.ShakeAttack(); } else // 일반 1, 2타 { CinemachineShake.Instance.HitSlow(0.1f, 0.2f); CinemachineShake.Instance.ShakeAttack(); } } // ⭐ 공격 애니메이션 마지막 프레임에 꼭 넣으세요! public void OnAttackEnd() { if (_comboCount == 3) // 막타가 끝났다면 후딜레이 시작 { StartCoroutine(PostComboRecovery()); } else { _isAttacking = false; // 1, 2타는 즉시 이동 가능 } } private IEnumerator PostComboRecovery() { _canAttack = false; _isAttacking = true; // 딜레이 중에도 이동 제한 yield return new WaitForSeconds(postComboDelay); _canAttack = true; _isAttacking = false; // 이제 움직이기 가능 _comboCount = 0; // 콤보 리셋 } public void CancelCharging() // 🛠️ 에러 해결: 확실하게 포함됨! { _isCharging = false; _chargeTimer = 0f; if (pAnim != null) pAnim.SetCharging(false); if (CinemachineShake.Instance != null) CinemachineShake.Instance.SetZoom(false); } public void ReleaseAttack() { if (!_isCharging || interaction.CurrentWeapon == null) return; pAnim.TriggerThrow(); pAnim.SetCharging(false); // 던지기 물리 로직 생략 (기존 것 유지) if (CinemachineShake.Instance != null) { CinemachineShake.Instance.HitSlow(0.15f, 0.3f); CinemachineShake.Instance.SetZoom(false); CinemachineShake.Instance.ShakeAttack(); } interaction.ClearCurrentWeapon(); stats.ResetWeight(); _isCharging = false; _chargeTimer = 0f; } public void StartCharging() { if (playerHealth != null && playerHealth.isHit) return; if (interaction.CurrentWeapon == null) return; _isCharging = true; _chargeTimer = 0f; pAnim.SetCharging(true); if (CinemachineShake.Instance != null) CinemachineShake.Instance.SetZoom(true); } public void StartWeaponCollision() { /* ... */ } public void StopWeaponCollision() { /* ... */ } }