본문으로 건너뛰기

카메라 디렉터

게임 이벤트 흐름에 맞춰 카메라 연출을 체인으로 조합합니다. Cinemachine보다 단순하고 게임 이벤트 흐름 중심으로 설계됐습니다.

구조

CameraDirector (MonoBehaviour, 코루틴 실행용)
— Camera 참조, 액션 시퀀스 실행

CameraAction (abstract, [Serializable])
├── ZoomCameraAction — FOV 변경
├── ShakeCameraAction — 진동
├── MoveCameraAction — 위치 이동
└── WaitCameraAction — 대기

빠른 시작

1. 씬에 CameraDirector 추가

CameraDirector 컴포넌트를 씬 오브젝트에 추가합니다. Camera 필드를 비워두면 Camera.main을 자동 사용합니다.

2. 단일 액션 재생

using AchUtils.Camera;

[SerializeField] CameraDirector cameraDirector;

cameraDirector.Play(new ShakeCameraAction
{
Duration = 0.5f,
Intensity = 0.3f,
Frequency = 30f
});

3. 시퀀스 재생

[SerializeField] CameraDirector cameraDirector;

cameraDirector.PlaySequence(new CameraAction[]
{
new MoveCameraAction
{
FollowTarget = boss.transform,
Duration = 1.5f,
Ease = AnimationCurve.EaseInOut(0,0,1,1)
},
new ZoomCameraAction { TargetFOV = 35f, Duration = 0.8f },
new WaitCameraAction { Duration = 2.0f },
new ShakeCameraAction { Duration = 0.5f, Intensity = 0.4f },
new ZoomCameraAction { TargetFOV = 60f, Duration = 1.0f },
});

API

CameraDirector

// 접근
CameraDirector cameraDirector

// 참조 카메라 (없으면 Camera.main)
Camera Camera

// 재생
void Play(CameraAction action)
void PlaySequence(IEnumerable<CameraAction> actions)
void Stop()

bool IsPlaying

event Action OnSequenceCompleted

ZoomCameraAction

float TargetFOV // 목표 시야각
float Duration
AnimationCurve Ease

ShakeCameraAction

float Duration
float Intensity // 진폭 크기
float Frequency // 진동 주파수 (Hz)
AnimationCurve AttenuationCurve // 강도 감쇠 곡선 (기본: 시작 강하게 → 약해짐)

MoveCameraAction

Vector3 Destination // 목표 위치 (FollowTarget이 없을 때)
Transform FollowTarget // 지정 시 해당 위치로 추적
float Duration
AnimationCurve Ease

WaitCameraAction

float Duration

완료 콜백

cameraDirector.OnSequenceCompleted += () =>
{
// 카메라 연출 완료 후 게임플레이 재개
player.EnableControl();
UI.ShowBossHealthBar();
};

cameraDirector.PlaySequence(bossIntroActions);

커스텀 액션 만들기

[Serializable]
public class RotateCameraAction : CameraAction
{
public Vector3 TargetAngle;
public float Duration;

public override IEnumerator Execute(CameraDirector director)
{
var cam = director.Camera.transform;
Quaternion startRot = cam.rotation;
Quaternion endRot = Quaternion.Euler(TargetAngle);
float elapsed = 0f;

while (elapsed < Duration)
{
elapsed += Time.deltaTime;
cam.rotation = Quaternion.Lerp(startRot, endRot, elapsed / Duration);
yield return null;
}

cam.rotation = endRot;
}
}

연출 예시 — 보스 등장

보스 감지 트리거

MoveCameraAction 보스 방향으로 1.5초 이동

ZoomCameraAction FOV 60→35 0.8초

WaitCameraAction 2초 대기 (보스 포효)

ShakeCameraAction 0.5초 진동

ZoomCameraAction FOV 35→60 1초 (원위치)

OnSequenceCompleted → UI 표시

::: tip SequenceRunner와 함께 SequenceRunnerCallbackStep으로 카메라 연출 시작 타이밍을 시퀀스에 끼워 넣을 수 있습니다. :::