117 lines
3.9 KiB
C#
117 lines
3.9 KiB
C#
using UnityEngine;
|
|
|
|
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.5f;
|
|
[SerializeField] private float fullChargeTime = 2f; // 차징 기준 시간
|
|
|
|
private float _lastAttackTime, _chargeTimer;
|
|
private bool _isCharging;
|
|
|
|
// UI와 이동 스크립트에서 참조하는 통로
|
|
public float ChargeProgress => Mathf.Clamp01(_chargeTimer / fullChargeTime);
|
|
public bool IsCharging => _isCharging;
|
|
|
|
private void Update()
|
|
{
|
|
if (_isCharging)
|
|
{
|
|
_chargeTimer += Time.deltaTime;
|
|
|
|
if (Input.GetMouseButtonDown(1))
|
|
{
|
|
CancelCharging();
|
|
Debug.Log("차징 취소됨");
|
|
}
|
|
}
|
|
}
|
|
|
|
public void PerformNormalAttack()
|
|
{
|
|
if (playerHealth != null && playerHealth.isHit) return;
|
|
if (interaction.CurrentWeapon == null || pAnim == null) return;
|
|
if (Time.time < _lastAttackTime + attackCooldown) return;
|
|
|
|
pAnim.TriggerAttack();
|
|
_lastAttackTime = Time.time;
|
|
}
|
|
|
|
public void StartWeaponCollision()
|
|
{
|
|
if (interaction.CurrentWeapon == null || weaponHitBox == null) return;
|
|
float damage = stats.BaseAttackDamage + interaction.CurrentWeapon.Config.BaseDamage;
|
|
weaponHitBox.EnableHitBox(damage);
|
|
}
|
|
|
|
public void StopWeaponCollision()
|
|
{
|
|
if (weaponHitBox != null) weaponHitBox.DisableHitBox();
|
|
}
|
|
|
|
public void ReleaseAttack()
|
|
{
|
|
if (!_isCharging || interaction.CurrentWeapon == null) return;
|
|
|
|
pAnim.TriggerThrow();
|
|
pAnim.SetCharging(false);
|
|
|
|
// 1. 레이캐스트 정밀 조준
|
|
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
|
Plane groundPlane = new Plane(Vector3.up, transform.position);
|
|
float rayDistance;
|
|
Vector3 targetDirection = transform.forward;
|
|
|
|
if (groundPlane.Raycast(ray, out rayDistance))
|
|
{
|
|
Vector3 pointOnGround = ray.GetPoint(rayDistance);
|
|
targetDirection = (pointOnGround - transform.position).normalized;
|
|
targetDirection.y = 0;
|
|
}
|
|
|
|
if (targetDirection != Vector3.zero) transform.rotation = Quaternion.LookRotation(targetDirection);
|
|
|
|
// 2. ⭐ [핵심 수정] 무기 컨피그에서 데이터 직접 가져오기
|
|
// 차징 시간에 따라 단계를 나눕니다. (1초 미만 Lv1, 1~2초 Lv2, 2초 이상 Lv3)
|
|
int lv = _chargeTimer >= 2f ? 3 : (_chargeTimer >= 1f ? 2 : 1);
|
|
|
|
// WeaponConfig에 있는 GetSpread와 GetForce 함수를 사용합니다.
|
|
float currentSpread = interaction.CurrentWeapon.Config.GetSpread(lv);
|
|
float throwForce = interaction.CurrentWeapon.Config.GetForce(lv);
|
|
|
|
// 3. 정확도(Spread)가 적용된 최종 방향 계산
|
|
Vector3 finalThrowDir = Quaternion.Euler(0, Random.Range(-currentSpread, currentSpread), 0) * targetDirection;
|
|
|
|
// 무기 던지기 실행
|
|
interaction.CurrentWeapon.OnThrown(finalThrowDir, throwForce, lv, stats);
|
|
|
|
// 상태 초기화
|
|
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);
|
|
}
|
|
|
|
public void CancelCharging()
|
|
{
|
|
_isCharging = false;
|
|
_chargeTimer = 0f;
|
|
if (pAnim != null) pAnim.SetCharging(false);
|
|
}
|
|
} |