득이공간
[Frozen Knights] NetRelevancy에 따른 클라이언트 Simulated Proxy 액터 자동 삭제 본문
개요
'다른 플레이어의 캐릭터가 부활할 때, 부활 모션 재생이 안되는' 문제를 해결하면서 얻은 경험을 공유하기 위해서 글을 작성한다.
위의 이미지처럼 원래는 Simulated Proxy(다른 플레이어) 캐릭터의 시작(or 부활) 애니메이션이 양쪽 모두에서 정상적으로 재생되어야 하는데,
아래 이미지처럼 간헐적으로 다른 클라이언트에서는 상대 캐릭터의 모션 및 모습이 보이지 않는 문제가 발생했다.
100퍼센트 미동작하는 것도 아니고 확률적으로 정상 동작할 때도 있었다.. ㅎㅎ
원인
중단점을 걸어서 확인해 보니 서버에서 몽타주 재생 RPC를 호출한 시점에 다른 클라이언트에서는 Simulated Proxy 캐릭터의 AnimInstance가 없었다.
현재 플레이어 캐릭터의 생명 주기는 다음과 같은데,
1. 애셋(메시, 애니메이션 등 리소스) 비동기 로딩
2. 시작(or 부활) 애니메이션 재생
3. 캐릭터 활성화 (bDead == false, bActivate == true)
...
(게임 플레이)
...
4. 죽음 애니메이션 재생 (bDead == true)
5. 캐릭터 비활성화 (bActivate == false) -> 이후 다시 2번 부터 반복됨
의도한대로 부활 모션 재생이 정상적으로 동작하려면 캐릭터가 1번을 마친 상태여야 하는데,
Simulated Proxy 캐릭터가 죽고, 비활성화되고 나서 2번이 아닌 1번 상태로 다시 돌아간 상황이었다.
해결
캐릭터의 주소를 로그로 찍어보니, 캐릭터가 부활할 때 해당 액터를 재사용하는 것이 아니라 새로운 액터가 생성되는 것을 확인했다.
혹시나 해서 찾아보니 언리얼이 Simulated Proxy 캐릭터가 비활성된 시점에 액터를 자동으로 삭제하고 있었다.
그래서 RPC 요청을 받을 때 액터를 새로 생성하면서 1번 동작(애셋 로딩)부터 다시 시작했던 것...
서버로부터 복제할 내용이 없는 경우 NetRelevancy에 따라서 Unreal은 성능을 위해 현재 클라이언트에서 ActorChannel을 닫고 → Actor를 Destroy()한다고 한다.
+) NetRelevancy 관련 상세
거리 벗어남 | NetCullDistanceSquared 초과 거리로 이동 |
Dormant 상태 | NetDormancy가 DORM_DormantAll이면 복제 중단 |
시야 밖 (optional) | FOV 바깥 Actor는 Relevancy에서 제외될 수 있음 |
너무 오래 업데이트 없음 | NetUpdateFrequency나 NetPriority에 의해 복제 대상에서 제외 |
커스텀 relevancy 오버라이드 | IsNetRelevantFor() 함수 오버라이드 결과 false |
따라서 자동으로 액터를 제거하는 동작을 방지하기 위해서 캐릭터에게 다음 값을 지정해주었다.
bAlwaysRelevant = true; // 모든 클라이언트에게 항상 복제
결론
하지만 무분별하게 bAlwaysRelevant 값을 true로 지정하면 트래픽이 폭증할 수 있다.
소유권이 없는 actor는 기본 설정대로 자동 관리하도록 하면서, 문제를 해결할 수 있는 방안을 찾아보아야 하겠다.
'GP > UE5 프로젝트' 카테고리의 다른 글
[Frozen Knights] 프로젝트 개요 (4) | 2025.06.25 |
---|