using UnityEngine; using System.Collections; public class PlayerMovement : MonoBehaviour { [Header("--- 참조 ---")] [SerializeField] private Stats stats; [SerializeField] private PlayerHealth health; [SerializeField] private PlayerAnimator pAnim; [SerializeField] private PlayerAttack attackScript; [Header("--- 대시 설정 ---")] // ⭐ 유저님 이미지(image_42ccbd.png) 수치를 기본값으로 적용했습니다. [SerializeField] private float dashDistance = 3f; [SerializeField] private float dashDuration = 0.08f; [SerializeField] private float dashCooldown = 1.5f; [Header("--- 차징 감속 설정 ---")] [Range(0.1f, 1f)] [SerializeField] private float minSpeedMultiplier = 0.3f; private Vector3 _moveDir; private bool _isSprinting; private bool _isDashing; private float _lastDashTime; // ⭐ PlayerInput에서 호출하는 입력 세팅 public void SetMoveInput(Vector3 dir, bool sprint) { _moveDir = dir; _isSprinting = sprint; } // ⭐ PlayerInput에서 Space를 누를 때 호출하는 대시 시도 함수 public void AttemptDash() { if (CanDash()) StartCoroutine(DashRoutine()); } private bool CanDash() { // 쿨타임 체크 + 대시 중 아님 + 사망 아님 bool isCooldownOver = Time.time >= _lastDashTime + dashCooldown; bool isAlive = health != null && !health.IsDead; return isCooldownOver && !_isDashing && isAlive; } private void Update() { // 1. 💀 사망, ⚡ 대시 중, 🤕 혹은 피격(isHit) 중일 때 이동 차단 if (health != null && (health.IsDead || health.isHit || _isDashing)) { if (pAnim != null && !health.IsDead) pAnim.UpdateMove(0f); return; } // 2. ⚔️ 공격 중(콤보 및 후딜레이)일 때 이동 차단 if (attackScript != null && attackScript.IsAttacking) { if (pAnim != null) pAnim.UpdateMove(0f); return; } // 3. 이동 속도 계산 및 차징 감속 적용 float speed = _isSprinting ? stats.CurrentRunSpeed : stats.CurrentMoveSpeed; if (attackScript != null && attackScript.IsCharging) { float speedReduction = Mathf.Lerp(1.0f, minSpeedMultiplier, attackScript.ChargeProgress); speed *= speedReduction; } // 4. 실제 이동 처리 transform.Translate(_moveDir * speed * Time.deltaTime, Space.World); // 5. 애니메이션 연동 if (pAnim != null) { float animVal = _moveDir.magnitude > 0.1f ? (_isSprinting ? 1.0f : 0.5f) : 0f; if (attackScript != null && attackScript.IsCharging) animVal *= 0.5f; pAnim.UpdateMove(animVal); } } // ⭐ [핵심] 방향성 대시 및 무적 처리 로직 private IEnumerator DashRoutine() { _isDashing = true; _lastDashTime = Time.time; // 입력 방향이 있으면 그쪽으로, 없으면 캐릭터의 정면이 아닌 후방(회피)으로 대시 Vector3 dashDir = _moveDir.sqrMagnitude > 0.001f ? _moveDir : -transform.forward; // 🛡️ [무적] 대시 시작 시 무적 상태 활성화 if (health != null) health.isInvincible = true; float startTime = Time.time; while (Time.time < startTime + dashDuration) { // 속도 = 거리 / 시간 float speed = dashDistance / dashDuration; transform.Translate(dashDir * speed * Time.deltaTime, Space.World); yield return null; } // 🛡️ [무적] 대시 종료 시 무적 상태 해제 if (health != null) health.isInvincible = false; _isDashing = false; } }