Projext/Assets/Scripts/Camera/Effects/CamShake.cs
2026-02-02 17:30:23 +09:00

78 lines
2.4 KiB
C#

using UnityEngine;
using Cinemachine;
using System.Collections;
public class CinemachineShake : MonoBehaviour
{
public static CinemachineShake Instance { get; private set; }
[Header("--- 컴포넌트 연결 ---")]
private CinemachineImpulseSource _impulseSource;
[SerializeField] private CinemachineVirtualCamera _vCam;
[Header("--- 줌 설정 ---")]
[SerializeField] private float defaultFOV = 60f;
[SerializeField] private float zoomedFOV = 45f;
[SerializeField] private float zoomSpeed = 5f;
private Coroutine _zoomCoroutine;
private void Awake()
{
Instance = this;
_impulseSource = GetComponent<CinemachineImpulseSource>();
if (_vCam == null) _vCam = GetComponent<CinemachineVirtualCamera>();
}
// ⭐ 렉 없는 타격감: 시간을 0.1배속으로 늘림 (Hit-Slow)
public void HitSlow(float duration = 0.15f, float timeScale = 0.1f)
{
StartCoroutine(DoHitSlow(duration, timeScale));
}
private IEnumerator DoHitSlow(float duration, float timeScale)
{
Time.timeScale = timeScale; // 멈추지 않고 아주 느리게
yield return new WaitForSecondsRealtime(duration);
Time.timeScale = 1.0f;
}
// ⭐ 카메라 킥: 순간적으로 FOV를 확 줄여 충격을 줌
public void CameraKick(float kickAmount = 8f)
{
if (_vCam == null) return;
_vCam.m_Lens.FieldOfView -= kickAmount; // 순간 줌인
SetZoom(false); // AnimateZoom을 통해 부드럽게 복구
}
public void ShakeAttack()
{
if (_impulseSource == null) return;
_impulseSource.GenerateImpulse(Vector3.down * 1.5f);
}
public void ShakeNoNo()
{
if (_impulseSource == null) return;
_impulseSource.GenerateImpulse(Vector3.right * 0.4f);
}
public void SetZoom(bool isZooming)
{
if (_vCam == null) return;
if (_zoomCoroutine != null) StopCoroutine(_zoomCoroutine);
float targetFOV = isZooming ? zoomedFOV : defaultFOV;
_zoomCoroutine = StartCoroutine(AnimateZoom(targetFOV));
}
private IEnumerator AnimateZoom(float target)
{
if (_vCam == null) yield break;
while (Mathf.Abs(_vCam.m_Lens.FieldOfView - target) > 0.1f)
{
_vCam.m_Lens.FieldOfView = Mathf.Lerp(_vCam.m_Lens.FieldOfView, target, Time.deltaTime * zoomSpeed);
yield return null;
}
_vCam.m_Lens.FieldOfView = target;
}
}