평소에 하던 프로젝트 내용은 아닙니다.
아는 선배가 같이 게임 개발 공부 해보지 않겠냐고 하셔서 또다른 언리얼 프로젝트를 개발하고 있습니다.
기능 구현을 주 목표로 하고 있는데 1년 넘게 삽질 하면서 듣도 보지도 못한 것을 근 3주만에 배웠습니다.
개인적으로 서버, 통신 쪽은 잼병이라 혼자 개발 할 때도 멀티플레이는 항상 나중으로 미뤘었는데 이 부분을 먼저 처리해주셔서 replicate를 제대로 고려해야 하는 상황을 직면했습니다.
해야한 일은 멀티 플레이에서 모든 모션이 동기화 되고, 기존의 FPS 템플릿에는 없는 전신 스켈레톤을 붙여야 했습니다.
스켈레톤을 붙이는 것 까지는 어떻게 됐는데 애니메이션 리플리케이션에서 일주일 넘게 막혔습니다.
덕분에 한 3일동안 먹는 족족 얹히기도 했고요.
문제는 당연히 "동기화가 되지 않는다." 입니다.
원인을 좀 꼽아보자면
1. RPC에 대한 이해 부족.
RPC를 안다고 생각했는데 이게 무엇인지만 알고 사용법은 몰랐던것 같습니다.
RPC 함수 호출을 어떻게 해야 하고 어떤 함수를 써야 하는지 아는데 이틀이 걸렸습니다.
2. 애니메이션에 대한 서툴름
애니메이션을 한번 만져봐서 자신 있었는데 안 만진 부분에서 4일 정도 시간을 먹었습니다.
특히 Montage Replicate를 하려고 하루에 12시간 넘게 인터넷 예시 코드를 따라 했었는데
결국 코드 문제는 아니었다고 합니다.
문제 해결하고 바로 글 쓰느라 뭔가 이상하네요.
저랑 비슷한 문제를 직면할 사람들을 위해 팁 형식으로 간단하게 정리하겠습니다.
1. RPC는 클라이언트가 UFUNCTION(Server, Reliable, WithValidation) 함수 A를 호출하면, A 함수가 서버에서 UFUNCTION(NetMulticast, Reliable) B 함수를 호출한다. 그럼 각 서버와 클라이언트에서 B 함수가 원하는 동작을 시행한다.
2. 선언 할 때는 A, B라 선언하지만 정의 할 때는 A_Implementation, B_Implementation라 정의해야 한다. 언리얼 코드 제너레이터가 뒤에 Implementation가 붙은 함수를 호출한다.
3. 추가로 bool A_Validate 함수가 필요하다. 아직까지 정확한 목적은 모르나 보통 return true만 넣어두면 정상 작동한다.
4. 모든 동작마다 replicate를 따로 해줘야 한다.
5. 발사와 같이 특정 방향 캐릭터 기준의 변수가 필요한 경우에는 UFUNCTION(Server, Reliable, WithValidation) 함수에 파라미터로 넘겨줘야 한다.
6. 몽타주 실행을 위한 AnimInstance는 5번을 생각해서 파라미터로 넘겨주면 문제가 생길 수 있다. AnimInstance는 Transient하다. UFUNCTION(NetMulticast, Reliable) 내부에서 생성하자.
7. 몽타주의 전체 재생 시간보다 blend 시간을 압도적으로 짧게 잡아야 한다. 그렇지 않으면 blend 하는 사이에 애니메이션이 끝나 결과적으로 애니메이션이 재생되지 않는 것처럼 보인다.
거의 하루에 1개씩 깨달음을 얻은 수준이네...
암튼 이 글이 누군가에게는 도움이 되어 저처럼 오랜시간 삽질하지 않기를 빕니다.