2026-02-12 15:23:25 +00:00
|
|
|
|
using UnityEngine; // 유니티 엔진의 기본 기능을 불러올거에요 -> UnityEngine을
|
2026-01-29 06:58:38 +00:00
|
|
|
|
|
2026-02-12 15:23:25 +00:00
|
|
|
|
public class PlayerAnimator : MonoBehaviour // 클래스를 선언할거에요 -> MonoBehaviour를 상속받는 PlayerAnimator를
|
2026-01-29 06:58:38 +00:00
|
|
|
|
{
|
2026-02-12 15:23:25 +00:00
|
|
|
|
[SerializeField] private Animator anim; // 변수를 선언할거에요 -> 애니메이터 컴포넌트 anim을
|
|
|
|
|
|
[SerializeField] private PlayerHealth health; // 변수를 선언할거에요 -> 플레이어 체력 스크립트 health를
|
2026-01-29 06:58:38 +00:00
|
|
|
|
|
|
|
|
|
|
// ⭐ 추가: 진짜 공격 로직이 있는 스크립트 연결
|
2026-02-12 15:23:25 +00:00
|
|
|
|
[SerializeField] private PlayerAttack attack; // 변수를 선언할거에요 -> 플레이어 공격 스크립트 attack을
|
2026-01-29 06:58:38 +00:00
|
|
|
|
|
2026-03-22 03:31:16 +00:00
|
|
|
|
// ── [v8] 일반 공격 애니메이션 속도 배율 ──────────────────────
|
|
|
|
|
|
[Header("=== 일반 공격 애니메이션 속도 ===")]
|
|
|
|
|
|
[Tooltip("일반 공격(좌클릭) 시 Throw 애니메이션 재생 속도 배율\n" +
|
|
|
|
|
|
"1.0 = 원본 속도, 2.0 = 2배 빠르게, 3.0 = 3배 빠르게\n" +
|
|
|
|
|
|
"연사가 빠를수록 높여야 애니메이션이 안 밀려요\n" +
|
|
|
|
|
|
"추천: 2.5~4.0")]
|
|
|
|
|
|
[Range(1f, 6f)]
|
|
|
|
|
|
[SerializeField] private float normalAttackAnimSpeed = 3.0f; // 변수를 선언할거에요 -> 일반 공격 시 애니 속도 배율을 (3배속 = 연사에 맞게 빠르게)
|
|
|
|
|
|
|
|
|
|
|
|
// ── 내부 캐싱 ──────────────────────────────────────────────
|
|
|
|
|
|
private float _defaultAnimSpeed = 1f; // 변수를 선언할거에요 -> 원본 애니메이터 속도를 저장할 변수를
|
|
|
|
|
|
|
2026-02-12 15:23:25 +00:00
|
|
|
|
private void Awake() // 함수를 실행할거에요 -> 스크립트 시작 시 Awake를
|
2026-01-29 06:58:38 +00:00
|
|
|
|
{
|
2026-03-22 03:31:16 +00:00
|
|
|
|
if (anim != null) _defaultAnimSpeed = anim.speed; // 저장할거에요 -> 애니메이터의 원본 속도를 (나중에 복원용)
|
|
|
|
|
|
|
2026-02-12 15:23:25 +00:00
|
|
|
|
if (health != null) // 조건이 맞으면 실행할거에요 -> 체력 스크립트가 있다면
|
2026-01-29 06:58:38 +00:00
|
|
|
|
{
|
2026-02-12 15:23:25 +00:00
|
|
|
|
health.OnHitEvent += () => anim.SetTrigger("Hit"); // 이벤트를 구독할거에요 -> 피격 시 Hit 트리거 발동을
|
|
|
|
|
|
health.OnDead += () => anim.SetBool("Die", true); // 이벤트를 구독할거에요 -> 사망 시 Die 상태 변경을
|
2026-01-29 06:58:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------
|
2026-03-22 03:31:16 +00:00
|
|
|
|
// ⭐ [애니메이션 이벤트 전달자]
|
2026-01-29 06:58:38 +00:00
|
|
|
|
// 애니메이션 창에 적은 이름과 똑같은 함수를 만듭니다.
|
|
|
|
|
|
// ---------------------------------------------------------
|
2026-02-12 15:23:25 +00:00
|
|
|
|
public void StartWeaponCollision() // 함수를 선언할거에요 -> 무기 충돌 시작 이벤트 StartWeaponCollision을
|
2026-01-29 06:58:38 +00:00
|
|
|
|
{
|
2026-02-12 15:23:25 +00:00
|
|
|
|
if (attack != null) attack.StartWeaponCollision(); // 실행할거에요 -> 공격 스크립트의 충돌 시작 함수를
|
2026-01-29 06:58:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-12 15:23:25 +00:00
|
|
|
|
public void StopWeaponCollision() // 함수를 선언할거에요 -> 무기 충돌 종료 이벤트 StopWeaponCollision을
|
2026-01-29 06:58:38 +00:00
|
|
|
|
{
|
2026-02-12 15:23:25 +00:00
|
|
|
|
if (attack != null) attack.StopWeaponCollision(); // 실행할거에요 -> 공격 스크립트의 충돌 종료 함수를
|
2026-01-29 06:58:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
|
|
|
|
|
2026-02-12 15:23:25 +00:00
|
|
|
|
public void UpdateMove(float speedValue) => anim.SetFloat("Speed", speedValue); // 값을 전달할거에요 -> 애니메이터의 Speed 파라미터에
|
2026-03-22 03:31:16 +00:00
|
|
|
|
|
|
|
|
|
|
// ── 기존 TriggerThrow (차징 공격용 — 원본 속도 재생) ────────
|
|
|
|
|
|
// Throw 트리거는 Animator Parameters에서 모든 레이어가 공유하므로
|
|
|
|
|
|
// Draw 레이어의 트랜지션 조건에 Throw가 있으면 정상 동작해요
|
|
|
|
|
|
public void TriggerThrow() // 함수를 선언할거에요 -> 차징 발사 시 Throw 트리거를 발동하는
|
|
|
|
|
|
{
|
|
|
|
|
|
if (anim == null) return; // 방어할거에요 -> 애니메이터가 없으면 스킵
|
|
|
|
|
|
anim.speed = _defaultAnimSpeed; // 복원할거에요 -> 차징 공격은 원본 속도로 재생 (일반 공격의 빠른 속도가 남아있을 수 있음)
|
|
|
|
|
|
anim.SetTrigger("Throw"); // 신호를 보낼거에요 -> 애니메이터의 Throw 트리거에
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ══════════════════════════════════════════════════════════
|
|
|
|
|
|
// [v8 신규] 일반 공격 전용 — 빠른 애니메이션 재생
|
|
|
|
|
|
// ══════════════════════════════════════════════════════════
|
|
|
|
|
|
//
|
|
|
|
|
|
// 문제: TriggerThrow()는 트리거 방식이라 이전 애니가 끝나야 다음이 재생됨
|
|
|
|
|
|
// → 연사 시 애니메이션이 화살 발사 속도를 못 따라감
|
|
|
|
|
|
//
|
|
|
|
|
|
// 해결: CrossFadeInFixedTime()으로 현재 애니를 강제 끊고 처음부터 재시작
|
|
|
|
|
|
// + 애니메이터 speed를 빠르게 올려서 쿨타임 안에 재생 완료
|
|
|
|
|
|
// + 애니 끝나면 원래 속도로 자동 복원
|
|
|
|
|
|
// ══════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// [v8] 일반 공격 시 호출 — Throw 애니메이션을 원래 속도로 강제 재시작해요.
|
|
|
|
|
|
/// 이전 애니가 재생 중이어도 즉시 끊고 처음부터 다시 재생해요.
|
|
|
|
|
|
/// 속도는 변경하지 않으므로 활 당기는 모션이 자연스럽게 보여요.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void PlayFastThrow() // 함수를 선언할거에요 -> Throw 애니메이션 강제 재시작을
|
|
|
|
|
|
{
|
|
|
|
|
|
if (anim == null) return; // 방어할거에요 -> 애니메이터가 없으면 스킵
|
|
|
|
|
|
|
|
|
|
|
|
// ── 1. 애니메이터 속도를 빠르게 설정 ──────────────────
|
|
|
|
|
|
// 화살은 즉시 발사되므로, 애니메이션도 빠르게 재생해야 시각적으로 맞아요
|
|
|
|
|
|
// normalAttackAnimSpeed (기본 3.0f) 배율로 빠르게 재생
|
|
|
|
|
|
anim.speed = normalAttackAnimSpeed; // 설정할거에요 -> 애니메이터 속도를 빠른 속도로 (연사에 맞게)
|
|
|
|
|
|
|
|
|
|
|
|
// ── 2. Draw 레이어(1번)에서 p_walk 애니메이션 강제 재시작 ──
|
|
|
|
|
|
// CrossFadeInFixedTime: 현재 어떤 애니가 재생 중이든 즉시 전환
|
|
|
|
|
|
// 트리거 방식은 이전 애니 끝나야 다음이 재생돼서 연사 시 밀림
|
|
|
|
|
|
// CrossFade는 재생 중이던 애니를 즉시 끊고 처음부터 다시 시작해요
|
|
|
|
|
|
// → 클릭할 때마다 활 쏘는 모션이 처음부터 보여요!
|
|
|
|
|
|
// 0.02f = 전환 블렌딩 시간 (거의 즉시 전환, 약간의 부드러움 유지)
|
|
|
|
|
|
// 1 = 레이어 1 (Draw Layer — 공격 애니메이션이 있는 레이어)
|
|
|
|
|
|
// 0f = 애니메이션 시작 지점 (처음부터)
|
|
|
|
|
|
anim.CrossFadeInFixedTime("p_walk", 0.02f, 1, 0f); // 재생할거에요 -> Draw 레이어의 p_walk 애니를 처음부터 즉시 강제 전환으로
|
|
|
|
|
|
|
|
|
|
|
|
// ── 3. 밀린 트리거 초기화 ────────────────────────────────
|
|
|
|
|
|
// 이전에 SetTrigger("Throw")가 쌓여있을 수 있으니 리셋해서
|
|
|
|
|
|
// 애니메이션이 중복 재생되는 것을 방지해요
|
|
|
|
|
|
anim.ResetTrigger("Throw"); // 초기화할거에요 -> 쌓여있던 Throw 트리거를 비우기
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// [v8] 빠른 공격 애니메이션 종료 후 원래 속도로 복원해요.
|
|
|
|
|
|
/// AttackRoutine 끝날 때 호출해서 이동 애니 등이 정상 속도로 재생되게 해요.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void ResetAnimSpeed() // 함수를 선언할거에요 -> 애니메이터 속도를 원래대로 복원하는
|
|
|
|
|
|
{
|
|
|
|
|
|
if (anim == null) return; // 방어할거에요 -> 애니메이터가 없으면 스킵
|
|
|
|
|
|
anim.speed = _defaultAnimSpeed; // 복원할거에요 -> 애니메이터 속도를 원본으로 (보통 1.0)
|
|
|
|
|
|
}
|
2026-02-27 00:44:52 +00:00
|
|
|
|
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────
|
|
|
|
|
|
// ⭐ 애니메이션 이벤트 전달자 — 활 관련 사운드
|
|
|
|
|
|
// FBX Throw 애니메이션 Events에 아래 함수 이름으로 등록해줘요
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
public void OnBowDraw() // 함수를 선언할거에요 -> 활 당기는 순간 소리 재생을 (애니메이션 이벤트)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (attack != null) attack.PlayBowDrawSound(); // 실행할거에요 -> 활 당기는 소리를
|
|
|
|
|
|
}
|
2026-02-12 15:23:25 +00:00
|
|
|
|
public void SetCharging(bool isCharging) => anim.SetBool("isCharging", isCharging); // 값을 설정할거에요 -> 애니메이터의 isCharging 불리언에
|
2026-01-29 06:58:38 +00:00
|
|
|
|
}
|