Ace Combat Zero: 유니티로 구현하기 #22 : 컷씬 (1)

Lunetis·2021년 7월 27일
0

Ace Combat Zero

목록 보기
23/27
post-thumbnail


꽤 오랜 시간동안 비행기 조작, 무기 제어, UI, 사운드 시스템을 만들며 "비행 슈팅 게임"의 기반을 구현해왔습니다.

그리고 어느 정도 게임의 윤곽이 잡힌 후에는, 이 프로젝트의 목표인 "에이스 컴뱃 제로의 마지막 미션"을 구현하는 데에 초점을 두고 있습니다.

페이즈 시스템, 각 페이즈별 특수 무기, 그리고 대사 및 자막 시스템을 만들면서, 일반적인 비행 슈팅 게임이 아닌 에이스 컴뱃처럼 보이기 위한 작업을 해왔죠.

각 페이즈에 맞는 전략을 활용해서 상대를 격추하는 게임 정도까지는 만들어진 상태입니다.


이제 미션 연출의 핵심인 컷씬(Cutscene) 연출을 만들 때입니다.

"ZERO" 미션의 전 과정을 온전히 체험할 수 있게 하는 것이 이 프로젝트의 목표였으니,
이 작업이 끝나면 프로젝트의 주 목표는 모두 완료한 것이나 다름없게 됩니다.



맵 만들기

지금까지 아주 조그만 맵에서 놀았었습니다. 테스트하다가 맵 밖으로 나가는 건 일상이었는데요,
이제 맵 밖이 안 보일 정도로 큰 맵을 만들어봅시다.

컷씬을 만들기 위해서는 미션에 맞는 맵을 만들어야 합니다.

이 미션의 미니맵입니다. 맵의 남쪽부터 이어지는 강 같은 게 보이는데요,



맵 구조는 이전 미션(The Valley of Kings / Operation Point Blank)에서 좀 더 자세히 볼 수 있습니다.

(마지막 미션과 동일한 맵입니다.)


미션 초반부에는 협곡 내부를 저공비행하면서 돌파해야 합니다.
미니맵에 강 형태로 보여지는 부분이 바로 플레이어가 돌파하는 협곡 구간입니다.


중간중간 다리도 보이고요.


6분 12초부터는 본격적으로 미사일 기지를 때려부수는 것으로 미션 목표가 갱신됩니다.
미사일 기지는 평지로 되어 있고, 군데군데 내부로 들어갈 수 있는 공간이 있습니다.

에이스 컴뱃 시리즈의 전통인 "터널 들어갔다 나오기"를 최종 미션이 아닌 바로 직전 미션에서 구현했죠.


그렇지만 그 내부 공간을 만들어줄 필요는 없습니다.

이전 미션에서만 쓰이고 마지막 미션에서는 닫히거든요.


하지만 초반 컷씬에 보이는 이 댐 부분은 구현을 해줘야 할 것 같습니다.



지형 및 텍스쳐 편집

기본 텍스쳐를 눈(snow)으로 두고 지형을 편집합니다.
남쪽의 협곡 부분도 적당히 구현해줍니다.


그 다음 Paint Texture 모드로 변경해서 저지대에 자갈이나 풀을 깔아줍니다.
물이 있는 곳은 식물이 자랄 여지가 있기 때문에 풀을 약간 깔았고요.


https://www.reddit.com/r/Unity3D/comments/9borx7/seans_water_free_water_shader_see_comments_for/

물 쉐이더를 구하기 위해 인터넷을 돌아다니다가 괜찮은 쉐이더를 하나 발견했습니다.

여기서 보면 나쁘지 않아 보이는데,

인게임에서는 빛을 받는 각도에서 봐야 볼만하네요.

그 다음에 이 댐은...

https://www.cadnav.com/3d-models/model-8240.html

어딘가에서 그럴듯한 댐 3D 모델을 가져왔습니다.

강이 끝나는 부분에 적당히 배치해준 다음, 모델링을 복사해서 대칭으로 배치시켜줬습니다.

댐 반대편은 물로 차 있어야 하는 것 아니냐고요?
사실 게임 내에서도 이 댐은 장벽의 성격이 강하지, 물을 저장하는 수단으로 보이지는 않습니다.

그리고 원본을 보면 물이 이 정도로 많지는 않아요.


댐 반대편은 미사일 기지를 나타내기 위해 콘크리트로 채워줍니다.

여러 개의 콘크리트 텍스쳐를 섞어서 쓰고, 곳곳에 눈을 칠해서 자연스럽게 만들어줍니다.



미사일 사일로

페이즈 2가 끝나면, 미사일 사일로의 해치가 슬라이드로 열리고 미사일이 발사됩니다.
해치가 육각형으로 되어있는 게 단순히 모델링 용량을 줄이려고 하는 것으로 보일 수도 있는데,

실제로 동그랗지 않고 각진 형태의 해치를 가진 사일로가 있었습니다.
그래서 그냥 해치를 육각형으로 만들어도 될 것 같네요.

이 미사일의 명칭은 V2입니다. 2차 세계대전 당시 독일의 탄도 미사일을 따온 것으로 보입니다.

매우 거대한 미사일인데, 이 모델링과 동일한 현실의 탄도 미사일을 찾지 못했습니다.

설정상 미사일 안에 여러 개의 탄두가 탑재된 MIRV(다탄두 재돌입 비행체)인데,
이런 종류의 미사일로 알려진 미국의 미니트맨 III, 러시아의 R-36 같은 걸 넣어볼까 하다가,


https://sketchfab.com/3d-models/v2-rocket-c12726a34e534e53af7134e22b1f9cca

그냥 진짜 V2를 넣죠?

크기를 재조정한 다음, 적당한 위치를 잡아서 미사일 사일로에 넣을 준비를 합니다.

잡은 위치에 Terrain - Set Height로 구멍을 내준 다음 미사일을 담아놓습니다.

매우 끔찍한 실력으로 미사일 사일로와 해치를 대강 만들어놓은 다음,

머테리얼을 땅이랑 비슷하게 맞춰서 미사일 사일로를 만들었습니다.

이 사일로 내부와 근처와 카메라들을 배치할 예정입니다.


그... 어... 저거 너무 눈에 띄는데...


몇 개 더 만들어서 바닥도 다시 칠해줍시다.

저같이 모델링을 못하는 사람은 원본처럼 지형을 만들기가 힘듭니다.
깃허브에 프로젝트를 공개해놨으니 더 대단하신 분이 이 지형을 편집해주길 기다리는 수밖에요.

최우선 목표는 멋진 맵을 만드는 게 아니라 컷씬에 필요한 소품(?)들을 배치하는 것입니다.



첫 번째 컷씬 제작

컷씬은 시네머신(Cinemachine)과 타임라인을 사용하려고 합니다.

컷씬을 만들기 위해서는 카메라 전환과 자막 출력 기능이 필요한데,
카메라는 시네머신 기능을 사용하고, 자막 출력 기능은 커스텀 트랙을 만들어서 처리해보겠습니다.

이전에 데스캠을 만들기 위해서 시네머신 카메라와 가상 카메라를 하나씩 만들어놨는데,

컷씬 전용으로 사용할 카메라를 하나 더 만들고, CinemachineBrain 컴포넌트를 추가합니다.


먼저 50초 분량의 첫 번째 컷씬을 제작해보겠습니다.

이 첫 번째 컷씬의 카메라들을 모두 잡는 것부터 시작하죠...



#1: 위에서 보여드렸던, 미사일이 발사되는 장면입니다.

미사일 해치가 오른쪽으로 움직이네요.

여기 안에 있는 사일로 내부에 카메라를 넣어줘야 합니다.

Virtual Camera를 하나 만들어서 첫 번째 사진의 위치에 맞게 카메라를 조정해줍니다.


카메라 조정 팁 : 카메라 또는 가상 카메라를 선택하고 Ctrl + Shift + F를 누르면 현재 시점으로 카메라의 시점이 이동합니다.
시점을 미리 맞춰둔 다음에 카메라를 생성하는 방법도 있습니다.

#2: 그 다음은 사일로를 비추는 위치로 가상 카메라를 세팅해줍니다.

가지고 있는 오브젝트로 세팅 놀이를 하면서 적당한 각도를 맞춰줍니다.

#3: 하늘에서 날아가는 미사일을 비춰줍니다. 이 때 카메라는 미사일에 시선을 고정합니다.

글쎄요, 이 쯤이면 될까요?

지형 디테일이 너무 심하게 차이가 나서 자괴감이 들 정도입니다.



미사일 이펙트

미사일이 내뿜는 불은 제트기에서 사용했던 이펙트를 살짝 손보고,
연기는 전투기가 발사하는 미사일의 연기 이펙트를 그대로 가져오겠습니다.


그리고 발사할 때 연기가 바닥에 부딪혀서 다시 지상으로 뿜어져 나오도록 만들어야 하는데,
이전에 임포트했던 파티클 에셋을 가져왔습니다.

밖에서 봤을때도 나름 그럴듯해보이는데요.



타임라인 (Timeline) 편집

이 오브젝트들을 모두 컨트롤할 수 있는 타임라인을 만들겠습니다.

Window - Sequencing - Timeline으로 창을 열어줍니다.

"[선택한 오브젝트]의 새 타임라인을 만들기 위해서, Director 컴포넌트와 타임라인 에셋을 만들어주세요."

Create를 누르면 타임라인 에셋 파일과 Playable Director 컴포넌트가 생성됩니다.

타임라인 창의 + 버튼을 누르면 여러가지 트랙을 추가할 수 있습니다.

주로 사용할 트랙은 Activation Track, Animation Track, Audio Track, Cinemachine Track입니다.

  • Activation Track : 오브젝트를 활성화/비활성화합니다.
  • Animation Track : 애니메이션을 재생합니다.
  • Audio Track : 오디오를 재생합니다.
  • Cinemachine Track : 시네머신 카메라를 제어합니다.

간단히 이 정도만 알고 넘어가겠습니다.

애니메이션 내부에 오브젝트를 활성화/비활성화하는 키프레임을 넣어둘 수도 있고, Activation Track에 처리하도록 맡겨둘 수도 있습니다. 이 부분은 개발자의 자유입니다.


먼저 미사일 해치가 열리고, 미사일이 발사되는 애니메이션을 만들겠습니다.

미사일을 화성으로 보내주는 애니메이션과,

미사일 해치는 열어주는 애니메이션을 각각 만들어놓습니다.

Timeline 창에서 애니메이션 트랙을 추가하고, 미사일과 사일로를 추가합니다.

그 다음 우클릭 또는 클립을 직접 드래그해서 트랙에 방금 만든 애니메이션 클립을 추가합니다.

그런데 이 상태로 실행을 해보면 미사일이 안 보입니다.

애니메이션 클립이 트랙에 배치될 때, 애니메이션의 주체가 이동하게 되는 경우 애니메이션 클립의 위치 오프셋이 원점으로 설정됩니다.
미사일 사일로 해치 애니메이션이 문제없이 실행되었던 이유는, 애니메이션의 주체가 사일로의 해치가 아닌 사일로 그 자체였기 때문입니다. (해치는 사일로의 자식 오브젝트로 있었습니다.)

애니메이션 제작자가 애니메이션에서 설정한 좌표를 사용하도록 Inspector 창에서 Remove Start Offset체크 해제해야 합니다.

이젠 또 미사일 회전값이 말썽입니다. 이 미사일의 X축 회전값이 0이 아니라 -90이거든요.
근데 이것도 0으로 초기화되고 있습니다.

애니메이션의 첫 번째 키프레임에서 회전값을 -90으로 고정합시다.

이제서야 미사일의 위치랑 회전이 제대로 된 모습입니다.

근데 사일로는 왜 다시 닫히죠? 저거 열려 있어야 하는데.


사일로 애니메이션을 선택하고, Animation Playable Asset - Loop을 Off로 설정합니다.


다시 닫히는 문제는 해결됐습니다.



시네머신 카메라 전환

카메라 전환은 정말 쉽습니다.

Cinemachine 트랙을 추가하고,

가상 카메라들을 여기다 모두 옮겨준 다음,

각 카메라를 활성화시킬 시간대를 적당히 맞춰줍니다.

실행하면... 안 바뀌죠. CutsceneCam이 그대로입니다.

왜냐하면 도대체 어떤 시네머신 카메라의 시점을 바꿔줄 것인지 설정하지 않았기 때문이죠.
시네머신 트랙에 Cinemachine Brain을 가지고 있는 카메라를 할당해줘야 합니다.

이제 시점이 제대로 맞춰지고 있습니다.


카메라 흔들기

(3번째 재탕)

발사될 때 카메라가 엄청 흔들리는데, 이것도 시네머신 기능을 이용해서 구현해봅시다.


시네머신 클립을 선택하고 Inspector 창에서 내려가다 보면 Noise 속성이 있습니다.

"Basic Multi Channel Perlin"을 선택하면 Noise Profile을 선택해야 합니다.
미사일 발사로 인한 진동을 표현해야 하니 강력해보이는 거 아무거나 선택하겠습니다.


그 다음에는 진동의 진폭(세기)과 주기(속도)를 설정합니다.

각각 0.2, 10으로 줬을 때의 예시입니다.


#2의 시점은 그대로 하면 되는데, 문제는 #1과 #3입니다.

#1은 미사일이 발사되기 전에는 떨리지 않다가 발사되기 시작하면 떨려야 하고,
#3은 미사일이 카메라에 가까워질수록 떨림이 심해져야 합니다.


뭐 어쩌겠습니까. 그냥 애니메이션 다 만들어줘야죠.


적당히 만들고 배치합시다.



미사일에 시점 고정하기

#3 카메라는 미사일에 시점을 고정시켜야 합니다.

시점 고정도 아주 간단합니다. Look At에 V2 미사일을 연결하면 알아서 고정시킵니다.

그리고 꽤나 높은 곳에서 비추는데도 불구하고 미사일이 크게 보이는 것을 보면,
카메라의 FOV 값이 상당히 낮아 보입니다.

Lens 하위 항목에 있는 FOV 항목도 같이 조절합니다.


이제 카메라 전환과 시점 등은 적당히 맞춰진 모습입니다.



게임 내 테스트

Scene에서는 직접 오브젝트를 선택하지 않는 이상 이펙트가 보이지 않습니다.
이펙트를 확인하기 위해 컷씬을 실행하는 함수를 추가합니다.

이 함수는 나중에 페이즈 3 진입 전에 실행되어야 합니다.



MissionZERO.cs

[SerializeField]
GameObject cutsceneCamera;
[SerializeField]
UnityEvent disableOnCutscene;

public void PlayPhase3Cutscene()
{
    disableOnCutscene.Invoke();
    GameManager.CameraController.GetActiveCamera().GetComponent<AudioListener>().enabled = false;

    cutsceneCamera.SetActive(true);
}

컷씬이 시작되기 전에 비활성화되어야 하는 스크립트들을 UnityEvent에 등록합니다.
함수를 실행하면 등록된 객체들과 현재 활성화된 카메라의 AudioListener를 비활성화한 후,

컷씬 전용 (CinemachineBrain 컴포넌트가 있는) 카메라를 활성화해줍니다.
카메라를 활성화할 때, 이 카메라에 달려있는 타임라인이 자동으로 실행됩니다.


비활성화해야하는 스크립트는 대부분 플레이어와 적 기체의 기능 관련 스크립트입니다.

InputManager의 디버깅용 입력 이벤트에 MissionZERO.PlayPhase3Cutscene()을 등록합니다.
이제 스페이스바를 누르면 바로 컷씬이 실행됩니다.


화성 갈끄니까아아아아아아아아아아

(4번째 재탕)

카메라 각도나 이펙트 퀄리티를 제외하면 어느 정도 자리가 잡힌 것 같습니다.



(2)편 밑밥 깔기

이런 식으로 카메라 구도를 잡는 것을 먼저 해결한 다음,
컷씬이 진행되는 동안 자막을 출력하고 키 입력을 막는 등의 처리도 추가해야 합니다.
(스킵 기능도 구현하고요)

카메라 세팅과 연출을 제작하는 건 프로그래머가 아닌 연출이나 애니메이션을 담당하는 부서에서 해줘야 할 것 같지만, 1인 개발인 이상 어쩔 수 없습니다. 혼자 다 만들어야죠.


끝내주는 노가다가 될 것 같아서 포스트를 남기고 마저 제작하러 가야겠습니다.


이 프로젝트의 작업 결과물은 Github에 업로드되고 있습니다.
https://github.com/lunetis/OperationZERO

0개의 댓글