새소식

개발/UE4

[UE4/Foliage] 절차 생성 폴리지 인스턴스 제거 후 세이브/로드시 이슈

  • -

상황

  • 절차적으로 생성한 폴리지 중 제거해야 하는 폴리지의 위치에 스트리밍되는 BP를 설치하는데, 해당 BP는 직렬화 되어 저장까지 된다.
  • 해당 BP에서 같은 위치에 같은 메쉬를 갖는 폴리지 인스턴스를 찾는 탐색 로직을 수행한다.
  • 이 탐색 로직에서 검출되지 않는 폴리지 인스턴스가 존재한다.
  • 이런 폴리지 인스턴스가 서버와 클라 각가에서 서로 다르게 생기기에 클라에선 고스팅 되는 폴리지가 발생, 서버에서는 새로운 폴리지 인스턴스가 생성되어 보이는 문제가 생긴다.
  • 기즈모를 통해 확인한 결과, 같은 메쉬를 갖고있다고 판단하지 않아 몇몇 폴리지 인스턴스들이 제거되지 않고 있었다.

예상 원인

  • 폴리지는 하이어라키적인 트리를 통해 관리되며, 파괴 생성시 이 트리가 재구성된다. (옵션 플래그에서 자동 재구성을 끄고 메뉴얼하게 관리할 수 도 있긴 하다.)
  • 트리 재구성 과정에서 위치와 바운딩 데이터들을 Swap하여 옮긴다. => 세이브 파일 로드시 이 스왑되는 인덱스들은 따로 저장되지 않기에 다른 위치에 다른 메쉬들이 생성되는 것 처럼 보인다.(BP 기준 관점)

해결 방안

  • 따라서, 폴리지 검출 방법에 있어 Mesh와 Location을 같이 검출하는 방법으로는 제대로 된 검출을 할 수 없다.
  • 이에, Location만을 이용해 검출을 시도해야 하는데 이를 위해서는 각 객체간의 최소 간격이 보장되어야 손실없이 안전하게 제거할 수 있다.
  • 완전 다른 방법으로는 인스턴스 삭제가 아닌, Scale Out을 하여 소거되어 보이도록 하고 Scale Out된 Indices를 서버에서 저장 후 클라와 동기화시키는 방법도 있다. 하지만, 현재 개발중인 게임은 폴리지 Instance를 16등분하고 스트리밍하고 있으며, 각각의 Foliage Instances 들이 상호간 참조해 트리를 구성하기에 제대로 된 Indices를 저장하고 동기화하는데는 문제가 있다.

실제 원인

  • 스트리밍 되는 폴리지 인스턴스를 제거하기 위해 레벨 내 객체들이 레이케스트, 박스캐스트와 같은 검출 검사를 한 뒤 삭제 후 결과를 캐싱해 반복 처리 되지 않도록 하고 있다.
  • 하지만 플레이어가 멀어져 스트리밍 인 - 아웃 과정을 반복하는 경우, 캐싱된 결과값을 처리해주지 않았기에 고스팅 이슈가 발생했었다.
  • 또한, 일부 폴리지 인스턴스의 메쉬가 바운더리를 제대로 갖추지 못해 캐스트 하는 크기에 문제가 있기도 하였다.

문제 해결

  • 스트리밍 되는 폴리지 인스턴스들만 따로 구하기가 어려웠기에, 플레이어로부터 일정 범위 안에 있는 탐지 객체들을 리프레쉬하는 쓰레드를 구성했다.
  • 해당 쓰레드에선 리프레쉬해야 할 객체들을 일정양씩 팬딩했다 처리해, CPU 쓰로틀링을 방지한다.

21/10/29

추가 이슈

  • 폴리지가 스트리밍 되기도 하고, 로컬 시뮬레이션으로 제거/생성되고 있는 상황에서 탐지할 때 Hit 구조체의 Item 인덱싱을 잘 못 참조해 엉뚱한 위치에 있는 폴리지를 제거하거나 생성하는 경우가 있었다.
  • 서버와 클라이언트의 폴리지 인덱스는 폴리지 트리가 리빌드 되면서 서로 맞지 않게 된다는 점을 유의할 필요가 있다.
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.