상호작용시 카메라 워크 알고리즘(e.g. 명조)
댓글 0
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요!
명조 스토리를 밀다가 문득 궁금해진 부분에 대한 탐구.
NPC와 대화할 때, 카메라의 위치와 회전을 조정하는 방법.

NPC와 대화할 때 카메라는 freeze 된다(즉, 유저가 조작할 수 없다)
또한, 카메라는 플레이어와 NPC를 동시에 한 화면으로 담아야 한다.
또한, 두 캐릭터의 대화 관련 애니메이션이 잘 보일 수 있도록 해야 한다.
위의 조건들을 만족하는 카메라 위치 및 각도를 유저의 NPC 상호작용 시(즉, 대화 시작 시) 짧은 시간 안에 찾아 적용 및 블렌딩하는 방법은?
플레이어가 위치한 점을 A라 하고 NPC가 위치한 점을 B라고 하자.
이때, A와 B의 y축(World-up. 하늘 방향) 좌표는 각 캐릭터 모델의 흉부 정도의 위치다.
그리고 A와 B를 잇는 직선 AB를 3:1로 분할한 지점을 O라고 하자.
눈대중으로 어림하니 명조의 카메라는 얼추 그 지점에 초점을 둔다.

대화 직전, 카메라가 다른 곳을 바라보고 있더라도 O 지점으로 회전한다.
또 카메라는 반드시 두 화자의 정면을 바라볼 수 있는 위치로 움직인다.
구체적으로는 4개의 Prefered position 이 있는 것으로 보인다.

1번과 2번 카메라는 Ob를 바라보는 Prefered Position이다.
3번과 4번 카메라는 Oa를 바라보는 Prefered Position이다.
즉, 이 경우 1번과 2번 카메라는 B의 얼굴을 볼 수 있는 위치이고, A의 뒷모습을 본다.
3번과 4번 카메라는 A의 얼굴을 볼 수 있고, B의 뒷모습을 보게 된다.
(인게임에서 다시 확인해보니 Ob만을 참조하는 것 같다. 로직상의 차이는 적다)
직선 AB의 중심을 C(center)라고 하자.
그리고, 아래 그림을 위에서 내려다 본다고 생각해보자.

점 C를 (0, 0)으로 하고 A와 B를 x축 또는 y축 위에 올리도록 좌표평면을 상상해보면, 네 개의 사분면에 각각 하나의 카메라가 위치함을 알 수 있다.
유저가 대화하기 직전, 화면에 송출되고 있던 카메라(Look Cam)의 위치를 P라고 하면, 점 P는 반드시 네 사분면 안에 위치하게 된다.
유저가 대화를 시작하면, Look Cam은 P가 위치하던 사분면 안의 Prefered position으로 블렌드 된다. 동시에, 타겟을 Oa 또는 Ob로 설정하여 rotation도 함께 블렌드 된다. 즉, 아래 의사코드와 같다.
// lookCamPos는 대화 이전 카메라의 위치
// 대화 이전 lookCam은 항상 플레이어(A)를 바라보므로 rot값은 필요 없음
int 사분면 = Get사분면(lookCamPos);
// A와 B를 기준으로 한 상대적 위치이므로, A와 B도 전달
Vector3 최종 카메라 위치 = GetPreferedPos(A, B, 사분면);
Quaternion 최종 카메라 회전 = GetPreferedRot(A, B, 사분면);
// 위치와 회전 적용
lookCam.Apply(최종 카메라 위치, 최종 카메라 회전)
// 이후 원래 위치로 돌아오는 것은 타겟만 다시 플레이어(A)로 바꿔도 됨.
장점은 설명하기 쉬운 메커니즘이라는 점, 그리고 동시에 납득하기 쉽다는 점.
반드시 A 또는 B를 바라보게 하므로 캐릭터 퀄리티가 강한 게임에서 유리한 듯.
가끔 아래처럼 가려버림. Collider가 있는 오브젝트면 피해 가는데, Mesh만 있는 오브젝트는 사실상 못 피하긴 함.

NPC가 벽에 붙어있으면 비슷한 문제 생길 듯. 이 경우 비교적 여유 공간이 넓은 사분면의 Prefered position을 참조하도록 하는 추가 로직이 필요할 수도 있음. 그래서 맵이 좁은 편이거나 골목길이 많은 맵에서는 다소 불리한 듯.
(5.24 추가: 명조는 저 상태에서 점 c를 피벗으로 한 카메라 회전이 가능하다.)
내가 개인 프로젝트 때 썼던 방법은 아래와 같다.
NPC 오브젝트 하위에 CamTarget을 넣고 이 Transform을 NPC가 참조한다. 대화시 카메라는 NPC에 접근하여 CamTarget을 가져와 이를 기반으로 화면을 조절한다.
아주 fancy한 방법을 알게 된 듯하다. 나중에 기회 되면 만들어야지.