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(); if (_vCam == null) _vCam = GetComponent(); } // ⭐ 렉 없는 타격감: 시간을 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; } }