공부/Unreal Engine 4

World Composition Level Streaming Problem when Teleporting

Lero God 2020. 11. 7. 15:06
월드 컴포지션 레벨 스트리밍 문제

 

[문제점]

  • 텔레포트 시 레벨들이 완전히 스트리밍이 완료되기 전에 캐릭터가 생성된다.

 

  • 아직 스트리밍 되지 않은 레벨에 캐릭터가 떨어지게 되면 아무 것도 없는 공중에서 계속 낙하한다.

 

[해결 방법]

  • 월드 컴포지션이 스트리밍 레벨들을 스트리밍 하는 방식을 이해하고 스트리밍 레벨들이 로드가 완료된 시점을 알 수 있는 방법을 찾는다.

 

  • 로드가 완료된 시점부터 캐릭터를 조작할 수 있게 할 방법을 찾는다.

 

 

레벨 로딩 방식 분석

 

[월드, 월드 컴포지션, 스트리밍 레벨, 레벨 간의 관계]

  • 월드는 월드 컴포지션과 레벨 배열을 갖고 있다.

 

  • 월드 컴포지션은 스트리밍 레벨 배열을 갖고 있다.

 

  • 스트리밍 레벨은 로드된 레벨을 갖고 있다.

 

[월드 컴포지션의 레벨 스트리밍 방식]

  • 월드 컴포지션은 PlayerController의 PlayerCameraManager의 위치를 기준으로

스트리밍 레벨과의 거리를 계산한다.

  • 스트리밍 레벨과의 거리가 지정한 레이어의 거리 기준 이내이면 스트리밍 레벨의 상태를 로딩 되야함으로 바꾼다.

 

[스트리밍 레벨의 로드 방식]

  • 월드의 StreamingLevelsToConsider 배열에 스트리밍 레벨을 추가한다.

 

  • 로드되야 하는 상태이면 RequestLevel 함수로 로드 요청을 한다.

 

  • RequestLevel 함수 내부적으론 LoadPackageAsync 함수를 호출해 레벨의 비동기 로딩을 요청한다.

 

  • LoadPackageAsync 함수를 호출하면 QueuedPackagesCounter 값이 증가한다.

 

  • LoadPackageAsync 함수의 인수로 로드가 완료됬을 시 호출할 AsyncLevelLoadComplete 함수와 바인딩한 델리게이트를 인수로 넘겨준다.

 

[월드의 레벨 로드 방식]

  • Tick마다 월드의 UpdateLevelStreaming 함수를 호출한다.

 

  • StreamingLevelsToConsider 배열에 있는 스트리밍 레벨들의 상태에 따른 처리를 한다.

 

[로딩이 완료된 시점]

  • 로딩이 완료되면 델리게이트와 바인딩된 AsyncLevelLoadComplete 함수를 호출한다.

 

  • SetLoadedLevel 함수에서 스트리밍 레벨에 로드된 레벨을 설정한다.

 

  • 월드의 레벨 배열에 로드된 레벨을 추가한다.

 

 

현재 레벨 로딩의 문제점

 

[비동기 로딩의 문제점]

  • 모든 레벨의 로딩을 완료한 시점을 알 수 없다.

 

  • 비동기 로딩을 하는 동안 월드의 Tick이 계속 호출된다.

 

[해결 방법]

  • 동기 로딩을 한다.

 

  • 동기 로딩을 하는 도중엔 월드의 Tick이 호출되지 않는다.

 

 

레벨의 동기

 

[동기 로딩 방식]

  • 월드에는 스트리밍 레벨의 동기 로딩을 지원하는 BlockTillLevelStreamingCompleted 함수가 있다.

 

  • BlockTillLevelStreamingCompleted 함수는 IsAsyncLoading 함수로 로딩되야 할 레벨이 있는 지 확인한다. 

 

  • IsAsyncLoading에선 QueuedPackagesCounter 값이 0보다 큰지 확인한다.

 

  • QueuedPackagesCounter 값이 0이면 로딩되야한 레벨이 없는 걸로 간주하고 동기 로딩을 하지 않는다.

 

[동기 로딩 중에 발생하는 문제]

  • QueuedPackagesCounter 값은 스트리밍 레벨에서 LoadPackageAsync 함수를 호출해야지 증가한다.

 

  • 언로드 되야할 레벨들이 가비지 컬렉팅이 되지 않았을 때 LoadPackageAsync 함수를 호출하지 않는다.


[문제점 해결 방법]

  • 스트리밍 레벨의 bShouldBlockOnLoad  bShouldBlockOnUnload 변수를 이용한다.

 

  • 위 변수들은 가비지 컬렉팅 문제를 무시하고 LoadPackageAsync 함수를 호출할 수 있게 한다.

 

[주의할 점]

  • 동기 로딩이 완료되면 bShouldBlockOnLoad  bShouldBlockOnUnload 변수들을 다시 false로 변경해줘야 한다.

 

'공부 > Unreal Engine 4' 카테고리의 다른 글

언리얼 엔진에서 dll의 사용성  (0) 2022.08.26
Build.cs에서 모듈의 private 폴더 경로 추가  (0) 2022.08.25
CSV String to Data Table(vice versa)  (0) 2020.09.08
UE4 Delegate  (0) 2020.09.03
UE4 플러그인 모듈 참조  (0) 2020.08.27