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(); } // 1. ⭐ [수정] 일반 공격 흔들림 (수직으로 묵직하게!) public void ShakeAttack() { if (_impulseSource == null) return; // Vector3.down 방향으로 힘을 주어 아래로 쾅! 찍는 느낌을 줍니다. _impulseSource.GenerateImpulse(Vector3.down * 0.5f); } // 2. ⭐ [수정] 힘 부족 시 도리도리 (수평으로 가볍게!) public void ShakeNoNo() { if (_impulseSource == null) return; // Vector3.right 방향으로 힘을 주어 고개를 좌우로 흔드는 느낌을 줍니다. _impulseSource.GenerateImpulse(Vector3.right * 0.4f); Debug.Log("[Shake] 힘 수치 부족! 도리도리 실행"); } 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) { if (_vCam == null) yield break; _vCam.m_Lens.FieldOfView = Mathf.Lerp(_vCam.m_Lens.FieldOfView, target, Time.deltaTime * zoomSpeed); yield return null; } _vCam.m_Lens.FieldOfView = target; } }