80 lines
7.3 KiB
C#
80 lines
7.3 KiB
C#
using UnityEngine; // 유니티 기본 기능(Time, Vector3, Coroutine 등)을 쓰기 위해 불러올거에요 -> UnityEngine를
|
|
using Cinemachine; // 시네머신 카메라/임펄스 기능을 쓰기 위해 불러올거에요 -> Cinemachine을
|
|
using System.Collections; // 코루틴(IEnumerator)을 쓰기 위해 불러올거에요 -> System.Collections를
|
|
|
|
public class CinemachineShake : MonoBehaviour // 클래스를 선언할거에요 -> 카메라 흔들림/줌/히트슬로우를 담당하는 CinemachineShake를
|
|
{ // 코드 블록을 시작할거에요 -> CinemachineShake 범위를
|
|
|
|
public static CinemachineShake Instance { get; private set; } // 프로퍼티를 선언할거에요 -> 싱글톤 인스턴스를 외부에서 읽기만 가능하게
|
|
|
|
[Header("--- 컴포넌트 연결 ---")] // 인스펙터에 제목을 표시할거에요 -> 컴포넌트 연결 섹션을
|
|
private CinemachineImpulseSource _impulseSource; // 변수를 선언할거에요 -> 임펄스(카메라 흔들림) 발사기 컴포넌트를 담을 _impulseSource를
|
|
[SerializeField] private CinemachineVirtualCamera _vCam; // 변수를 선언할거에요 -> 조절할 가상 카메라를 담을 _vCam을
|
|
|
|
[Header("--- 줌 설정 ---")] // 인스펙터에 제목을 표시할거에요 -> 줌 설정 섹션을
|
|
[SerializeField] private float defaultFOV = 60f; // 변수를 선언할거에요 -> 기본 FOV를 defaultFOV에
|
|
[SerializeField] private float zoomedFOV = 45f; // 변수를 선언할거에요 -> 줌인 FOV를 zoomedFOV에
|
|
[SerializeField] private float zoomSpeed = 5f; // 변수를 선언할거에요 -> 줌 보간 속도를 zoomSpeed에
|
|
|
|
private Coroutine _zoomCoroutine; // 변수를 선언할거에요 -> 현재 실행 중인 줌 코루틴을 담을 _zoomCoroutine을
|
|
|
|
private void Awake() // 함수를 선언할거에요 -> 오브젝트가 켜질 때 1번 실행되는 Awake를
|
|
{ // 코드 블록을 시작할거에요 -> Awake 범위를
|
|
Instance = this; // 값을 넣을거에요 -> 싱글톤 인스턴스를 자기 자신으로 설정
|
|
_impulseSource = GetComponent<CinemachineImpulseSource>(); // 컴포넌트를 가져올거에요 -> 내 오브젝트에서 임펄스 소스를 찾아 저장
|
|
if (_vCam == null) _vCam = GetComponent<CinemachineVirtualCamera>(); // 조건이 맞으면 실행할거에요 -> vCam이 비어있으면 내 오브젝트에서 찾아 채우기
|
|
} // 코드 블록을 끝낼거에요 -> Awake를
|
|
|
|
// ⭐ 렉 없는 타격감: 시간을 0.1배속으로 늘림 (Hit-Slow) // 설명을 적을거에요 -> 짧게 슬로모션을 걸어 타격감을 올리는 기능
|
|
public void HitSlow(float duration = 0.15f, float timeScale = 0.1f) // 함수를 선언할거에요 -> duration/timeScale로 히트슬로우를 주는 HitSlow를
|
|
{ // 코드 블록을 시작할거에요 -> HitSlow 범위를
|
|
StartCoroutine(DoHitSlow(duration, timeScale)); // 코루틴을 실행할거에요 -> 실제 슬로우 처리를 하는 DoHitSlow를
|
|
} // 코드 블록을 끝낼거에요 -> HitSlow를
|
|
|
|
private IEnumerator DoHitSlow(float duration, float timeScale) // 코루틴 함수를 선언할거에요 -> 히트슬로우를 수행하는 DoHitSlow를
|
|
{ // 코드 블록을 시작할거에요 -> DoHitSlow 범위를
|
|
Time.timeScale = timeScale; // 값을 바꿀거에요 -> 전체 게임 시간을 느리게(멈춤은 아님)
|
|
yield return new WaitForSecondsRealtime(duration); // 기다릴거에요 -> 실제 시간 기준으로 duration만큼
|
|
Time.timeScale = 1.0f; // 값을 복구할거에요 -> 게임 시간을 정상(1)으로
|
|
} // 코드 블록을 끝낼거에요 -> DoHitSlow를
|
|
|
|
// ⭐ 카메라 킥: 순간적으로 FOV를 확 줄여 충격을 줌 // 설명을 적을거에요 -> 순간 줌인 후 부드럽게 복구시키는 연출
|
|
public void CameraKick(float kickAmount = 8f) // 함수를 선언할거에요 -> FOV를 순간 감소시키는 CameraKick을
|
|
{ // 코드 블록을 시작할거에요 -> CameraKick 범위를
|
|
if (_vCam == null) return; // 조건이 맞으면 종료할거에요 -> 카메라가 없으면 처리 불가
|
|
_vCam.m_Lens.FieldOfView -= kickAmount; // 값을 바꿀거에요 -> FOV를 줄여서 순간 줌인 효과
|
|
SetZoom(false); // 함수를 실행할거에요 -> 기본 FOV로 부드럽게 돌아가도록 줌 애니메이션 시작
|
|
} // 코드 블록을 끝낼거에요 -> CameraKick을
|
|
|
|
public void ShakeAttack() // 함수를 선언할거에요 -> 공격용 흔들림을 주는 ShakeAttack을
|
|
{ // 코드 블록을 시작할거에요 -> ShakeAttack 범위를
|
|
if (_impulseSource == null) return; // 조건이 맞으면 종료할거에요 -> 임펄스 소스가 없으면 불가
|
|
_impulseSource.GenerateImpulse(Vector3.down * 1.5f); // 임펄스를 발생시킬거에요 -> 아래 방향으로 강하게 흔들기
|
|
} // 코드 블록을 끝낼거에요 -> ShakeAttack을
|
|
|
|
public void ShakeNoNo() // 함수를 선언할거에요 -> 좌우로 살짝 흔드는 ShakeNoNo를
|
|
{ // 코드 블록을 시작할거에요 -> ShakeNoNo 범위를
|
|
if (_impulseSource == null) return; // 조건이 맞으면 종료할거에요 -> 임펄스 소스가 없으면 불가
|
|
_impulseSource.GenerateImpulse(Vector3.right * 0.4f); // 임펄스를 발생시킬거에요 -> 오른쪽 방향으로 약하게 흔들기
|
|
} // 코드 블록을 끝낼거에요 -> ShakeNoNo를
|
|
|
|
public void SetZoom(bool isZooming) // 함수를 선언할거에요 -> 줌인/줌아웃 목표를 설정하는 SetZoom을
|
|
{ // 코드 블록을 시작할거에요 -> SetZoom 범위를
|
|
if (_vCam == null) return; // 조건이 맞으면 종료할거에요 -> 카메라가 없으면 불가
|
|
if (_zoomCoroutine != null) StopCoroutine(_zoomCoroutine); // 조건이 맞으면 실행할거에요 -> 기존 줌 코루틴이 있으면 중지해서 중첩 방지
|
|
float targetFOV = isZooming ? zoomedFOV : defaultFOV; // 목표 FOV를 정할거에요 -> 줌이면 zoomedFOV, 아니면 defaultFOV
|
|
_zoomCoroutine = StartCoroutine(AnimateZoom(targetFOV)); // 코루틴을 실행할거에요 -> 목표 FOV로 부드럽게 이동하는 AnimateZoom을
|
|
} // 코드 블록을 끝낼거에요 -> SetZoom을
|
|
|
|
private IEnumerator AnimateZoom(float target) // 코루틴 함수를 선언할거에요 -> FOV를 목표값까지 보간하는 AnimateZoom을
|
|
{ // 코드 블록을 시작할거에요 -> AnimateZoom 범위를
|
|
if (_vCam == null) yield break; // 조건이 맞으면 중단할거에요 -> 카메라가 없으면 코루틴 종료
|
|
while (Mathf.Abs(_vCam.m_Lens.FieldOfView - target) > 0.1f) // 반복할거에요 -> 현재 FOV가 목표값과 충분히 가까워질 때까지
|
|
{ // 코드 블록을 시작할거에요 -> 보간 루프
|
|
_vCam.m_Lens.FieldOfView = Mathf.Lerp(_vCam.m_Lens.FieldOfView, target, Time.deltaTime * zoomSpeed); // 값을 보간할거에요 -> 현재 FOV를 target 쪽으로 부드럽게
|
|
yield return null; // 다음 프레임까지 기다릴거에요 -> 프레임 단위로 갱신
|
|
} // 코드 블록을 끝낼거에요 -> 보간 루프
|
|
_vCam.m_Lens.FieldOfView = target; // 값을 확정할거에요 -> 마지막에 정확히 target으로 맞추기
|
|
} // 코드 블록을 끝낼거에요 -> AnimateZoom을
|
|
|
|
} // 코드 블록을 끝낼거에요 -> CinemachineShake를 |