언리얼 엔진에서 레벨 스트리밍 방법
게임 환경(레벨)은 지하동굴과 같은 환경일 수도 있고 지상의 개활지와 같은 환경일 수도 있다. 또한 이런 환경들이 결합되어 시시각각 다른 환경으로 전환되면서 진행될 수도 있다.
동굴과 밖을 오가며 게임이 진행된다면 동굴 속에서는 보이지 않는 바깥 환경은 화면에 보일 필요가 없으므로 메모리에 저장해 둘 필요가 없을 것이다. 이런 경우에 한동안 화면에서 보이지 않는 일부의 레벨을 메모리에서 제거하려면 레벨 스트리밍(Level Streaming) 방법을 적용해야 한다
레벨 스트리밍을 사용하기 위해서는 하나의 큰 레벨을 사용하지 않고 다수개의 레벨 파일을 생성하여 각각의 레벨파일에 액터를 나누어 저장하고 해당 레벨을 실행시간에 필요시마다 로드/언로드하여 메모리 사용량을 줄일 수 있다.
블루프린트에서 특정 레벨파일을 메모리에 로드/언로드하려면 Load Stream Level / Unload Stream Level 함수노드를 사용하면 된다
Level Streaming Volume을 사용하면 트리거 볼륨과 블루프린트를 사용하지 않아도 카메라가 볼륨 안에 위치하면 해당 레벨파일을 자동으로 로드해주므로 편리하다. 볼륨을 약간 겹치도록 설정하면 레벨이 끊어지지 않도록 보이게 할 수도 있다
퍼시스턴트 레벨
- 항상 로드되어 있는 레벨
스트리밍 레벨
- 필요시마다 로드/언로드할 수 있는 레벨
디폴트로 생성된 레벨은 퍼시스턴트 레벨이다
퍼시스턴트 레벨과 분리하여 실행시간에 로드/언로드하고자 하는 레벨은 스트리밍 레벨이라고 한다
스트리밍 레벨파일은 레벨 관리창에서 생성할 수 있고 별도의 레벨파일에 저장해야 한다
퍼시스턴트 레벨은 언로드할 수 없고 항상 로드된 상태이다
스트리밍 레벨 관리창 열기
언리얼 에디터의 메뉴 > 창 > 레벨
[레벨] 콤보박스를 누르고 [새로 생성...]을 선택하면 스트리밍 레벨을 저장할 레벨파일을 새로 생성할 수 있다
스트리밍 레벨 파일을 저장할 폴더를 생성하거나 선택한다
레벨파일이 생성되면 [퍼시스턴트 레벨] 노드의 하위에 포함되고 파란색으로 선택된 상태가 된다.
위와 같이 현재 파란색으로 선택된 레벨이 있을 경우에 에디터로 드래그하여 새로 액터를 추가하거나 새로 복사하여 생성되는 액터는 모두 현재 선택된 레벨에 포함되어 해당 레벨파일에 저장된다
스트리밍 레벨에 액터 추가하기
위와 같이 특정 스트리밍 레벨이 선택된 상태에서 언리얼 에디터로 나가서 퍼시스턴스 레벨에 포함된 플로어를 ALT키를 눌러 복사하면 복사된 플로어는 레벨 관리창에서 현재 선택된 스트리밍 레벨에 저장된다
모드 > 기본 을 선택하고 Sphere등도 드래그하여 레벨에 배치하는 경우에도 레벨 관리창에서 현재 선택된 레벨에 포함된다
CB에서 드래그하여 뷰포트에 놓는 경우에도 레벨 관리창에 현재 선택된 레벨에 포함되어 저장된다
카메라가 스트리밍 레벨의 근처로 접근할 경우 해당 레벨 로드하기
보이지 않는 스트리밍 레벨의 근처에 트리거 볼륨을 배치하고 카메라가 트리거 볼륨에 들어오면 특정 스트리밍 레벨을 로드하고 보여주는 예를 작성해보자
아래의 그림처럼 카메라가 스트리밍 레벨 근처에 접근하면 알 수 있도록 Trigger Volume를 배치한다. 이 때 볼륨을 드래그하여 레벨에 배치할 때는 반드시 레벨 관리창에서 퍼시스턴트 레벨이 파란색으로 선택된 상태이어야 한다. 레벨 관리창에서 퍼시스턴트 레벨을 더블클릭하거나 마우스 우측을 누르고 [현재로 만들기]를 누르면 파란색으로 선택된다. 그래야만 퍼시스턴트 레벨의 레벨블루프린트에서 트리거 볼륨의 참조에 접근할 수 있고 충돌 이벤트를 정의할 수 있다.
만약 트리거 볼륨을 드래그하여 배치할 때 레벨 관리창에서 퍼시스턴트 레벨이 아닌 다른 레벨이 파란색으로 선택되어 있다면 퍼시스턴트 레벨의 레벨블루프린트에서 트리거의 참조를 얻을 수 없으므로 먼저 트리거 볼륨을 퍼시스턴트 레벨로 이동해야 한다.
아래 그림처럼 레벨 에디터에서 트리거 볼륨을 선택하고 레벨 관리창의 퍼시스턴스 레벨에 마우스 우측을 누르고 [선택된 액터를 레벨로 이동] 항목을 클릭하면 이동할 수가 있다
레벨 관리창에서 퍼시스턴트 레벨의 [레벨 블루프린트 열기] 아이콘을 클릭한다
스트리밍 레벨의 로드 및 언로드
퍼시스턴트 레벨의 레벨 블루프린트 그래프에 다음과 같이 입력한다
카메라가 트리거 볼륨에 들어오면 Load Stream Level 함수 노드와 스트리밍 레벨 파일의 이름을 이용하여 레벨을 로드하는 명령이다. 언로드할 때는 Unload Stream Level 함수 노드를 사용하면 된다
게임을 실행하고 카메라를 트리거 볼륨 안으로 이동해보면 스트리밍 레벨이 로드되고 화면에 출력되는 것을 확인할 수 있다
레벨 스트리밍 볼륨(Level Streaming Volume) 사용하기
레벨 스트리밍 볼륨(Level Streaming Volume)을 사용하면 트리거 볼륨과 블루프린트를 사용하지 않고도 위와 같은 효과를 낼 수가 있다. 레벨 스트리밍 볼륨 안에 카메라가 들어오면 그 볼륨과 연결된 스트리밍 레벨 파일이 자동으로 로드되고 나가면 레벨파일이 언로드된다
레벨 스트리밍 볼륨 설정
각각의 스트리밍 레벨 파일은 반드시 필요하다
레벨 관리창에서 퍼시스턴트 레벨을 파란색이 되도록 선택하고 레벨 스트리밍 볼륨을 뷰포트에 배치한다
퍼시스턴트 레벨은 항상 로드되어 있어야 하는 레벨이므로 스트리밍 레벨이 로드되지 않았을 때라도 레벨 스트리밍 볼륨은 퍼시스턴트 레벨에 존재해야만 카메라의 접근을 볼륨이 감지하여 다른 스트리밍 레벨을 로드하는 트리거로 사용될 수 있기 때문이다.
레벨 관리창에서 연결하고자 하는 레벨파일을 선택하고 [레벨 디테일] 아이콘을 클릭하여 디테일 창을 연다
[Streaming Volumes] 항목 우측의 + 아이콘을 클릭하여 노드를 생성하고
[Streaming Volumes] 항목 좌측의 조그만 삼각형을 클릭하여 노드를 노출시킨다
나타난 콤보박스를 클릭하여 현재의 레벨파일에 연결(바인드)하고자 하는 Streaming Volume의 이름을 찾아 선택한다
이렇게 바인드된 레벨 스트리밍 볼륨 안에 카메라가 들어가면 바인드된 레벨파일이 자동으로 로드되고 화면에 보여진다
레벨 스트리밍 볼륨의 크기는 제한이 없고 포함하는 레벨 전체를 덮을 필요도 없지만 상식적으로 레벨 전체를 덮어줘야 해당 레벨 안에서 이동 중일 때 볼륨 밖으로 나가게 되면 레벨이 사라지므로 볼륨이 해당 레벨 전체를 충분히 감싸 주는 것이 좋겠다.
레벨 스트리밍 볼륨의 영역과 포함하는 레벨의 영역이 반드시 일치할 필요는 없으나 카메라가 이동시에 없었던 레벨이 갑자기 나타나는 비현실적 상황을 방지하기 위해서는 레벨 전체를 덮고 인접 레벨도 일부 포함하는 것이 좋다
C++에서 밀리초(Milliseconds) 사용하는 예
#include <chrono> // c++ 11부터 지원
// ...
using namespace std::chrono;
milliseconds start = duration_cast< milliseconds >(
system_clock::now().time_since_epoch()
);
// 측정 대상 로직
milliseconds end = duration_cast< milliseconds >(
system_clock::now().time_since_epoch()
);
cout <<"처리 경과시간:" << end.count() - start.count() << endl;