using UnityEngine; // 유니티 기능을 불러올거에요 -> UnityEngine을
///
/// 화살 명중 시 타격감을 강화하는 매니저
/// 히트스톱(프레임 멈춤) + 카메라 흔들림 + 넉백을 통합 처리
/// 싱글톤 — CinemachineShake와 같은 오브젝트에 붙이거나 별도 빈 오브젝트에 부착
///
public class HitImpactManager : MonoBehaviour // 클래스를 선언할거에요 -> 타격 임팩트를 관리하는 HitImpactManager를
{
public static HitImpactManager Instance { get; private set; } // 프로퍼티를 선언할거에요 -> 싱글톤 인스턴스를
[Header("--- 히트스톱 (프레임 정지) ---")] // 인스펙터 제목을 달거에요 -> 히트스톱 설정을
[Tooltip("일반 공격 히트스톱 지속 시간 (초)")]
[SerializeField] private float normalHitStopDuration = 0.05f; // 변수를 선언할거에요 -> 일반 히트스톱 시간을
[Tooltip("차징/속성 공격 히트스톱 지속 시간 (초)")]
[SerializeField] private float strongHitStopDuration = 0.1f; // 변수를 선언할거에요 -> 강한 히트스톱 시간을
[Tooltip("히트스톱 중 타임스케일 (0에 가까울수록 느림)")]
[SerializeField] private float hitStopTimeScale = 0.02f; // 변수를 선언할거에요 -> 히트스톱 중 시간 배율을
[Header("--- 카메라 흔들림 ---")] // 인스펙터 제목을 달거에요 -> 카메라 흔들림 설정을
[Tooltip("일반 공격 흔들림 강도")]
[SerializeField] private float normalShakeIntensity = 1.0f; // 변수를 선언할거에요 -> 일반 흔들림 강도를
[Tooltip("차징/속성 공격 흔들림 강도")]
[SerializeField] private float strongShakeIntensity = 2.5f; // 변수를 선언할거에요 -> 강한 흔들림 강도를
[Header("--- 넉백 ---")] // 인스펙터 제목을 달거에요 -> 넉백 설정을
[Tooltip("일반 공격 넉백 거리")]
[SerializeField] private float normalKnockbackForce = 1.5f; // 변수를 선언할거에요 -> 일반 넉백 힘을
[Tooltip("차징/속성 공격 넉백 거리")]
[SerializeField] private float strongKnockbackForce = 3.5f; // 변수를 선언할거에요 -> 강한 넉백 힘을
[Tooltip("넉백 지속 시간 (초)")]
[SerializeField] private float knockbackDuration = 0.15f; // 변수를 선언할거에요 -> 넉백 지속 시간을
[Header("--- 카메라 킥 (FOV 펀치) ---")] // 인스펙터 제목을 달거에요 -> 카메라 킥 설정을
[Tooltip("명중 시 순간 FOV 줌인 양 (강한 공격만)")]
[SerializeField] private float hitCameraKick = 3f; // 변수를 선언할거에요 -> 카메라 킥 양을
private void Awake() // 함수를 실행할거에요 -> 초기화 Awake를
{
if (Instance == null) Instance = this; // 조건이 맞으면 설정할거에요 -> 싱글톤 인스턴스를
else Destroy(gameObject); // 조건이 틀리면 파괴할거에요 -> 중복 인스턴스를
}
///
/// 화살 명중 시 호출 — 모든 타격감 효과를 한 번에 실행
///
/// 맞은 몬스터
/// 화살 진행 방향 (넉백 방향)
/// 명중 위치
/// 강한 공격 여부 (차징/속성)
public void TriggerHitImpact(MonsterClass monster, Vector3 hitDirection, Vector3 hitPoint, bool isStrongHit) // 함수를 선언할거에요 -> 타격 임팩트를 실행하는 TriggerHitImpact를
{
// 1. 히트스톱 (프레임 정지)
float stopDuration = isStrongHit ? strongHitStopDuration : normalHitStopDuration; // 값을 결정할거에요 -> 공격 강도에 따라 히트스톱 시간을
if (CinemachineShake.Instance != null) // 조건이 맞으면 실행할거에요 -> 카메라 매니저가 있다면
{
CinemachineShake.Instance.HitSlow(stopDuration, hitStopTimeScale); // 실행할거에요 -> 히트스톱을
}
// 2. 카메라 흔들림
float shakeIntensity = isStrongHit ? strongShakeIntensity : normalShakeIntensity; // 값을 결정할거에요 -> 흔들림 강도를
if (CinemachineShake.Instance != null) // 조건이 맞으면 실행할거에요 -> 카메라 매니저가 있다면
{
CinemachineShake.Instance.ShakeAttack(); // 실행할거에요 -> 카메라 흔들림을
}
// 3. 카메라 킥 (강한 공격만)
if (isStrongHit && CinemachineShake.Instance != null) // 조건이 맞으면 실행할거에요 -> 강한 공격이고 카메라가 있다면
{
CinemachineShake.Instance.CameraKick(hitCameraKick); // 실행할거에요 -> FOV 펀치 효과를
}
// 4. 넉백
if (monster != null) // 조건이 맞으면 실행할거에요 -> 몬스터가 있다면
{
float knockForce = isStrongHit ? strongKnockbackForce : normalKnockbackForce; // 값을 결정할거에요 -> 넉백 힘을
Vector3 knockDir = hitDirection.normalized; // 방향을 정규화할거에요 -> 넉백 방향을
knockDir.y = 0f; // 값을 바꿀거에요 -> 수평 넉백만 적용하게
monster.ApplyKnockback(knockDir, knockForce, knockbackDuration); // 실행할거에요 -> 몬스터 넉백 함수를
}
}
}