[UnrealBlueprint]언리얼 블루프린트 자동 스크린샷 / Automatic Screenshot

2022. 3. 16. 16:42unreal/Unreal Blueprint

언리얼로 제작중이던 프로젝트가 유니티로 옮겨지며 3d게임이 2d게임으로 변경된 적이 있습니다(결국은 3d로 다시 변경됨^^)

유니티 상에서 3d모델을 이미지로 렌더링해 스프라이트 이미지로 사용하길 바랐으나

렌더링 퀄리티문제로(유니티에서 렌더링시 너무 화면이 쨍한 느낌이 강하다고하였음) 언리얼에서 이미지를 렌더링하고

그 이미지만 유니티에 스프라이트로 사용하게되었고

스프라이트 작업의 문제점인 스크린샷 노가다를 하게되어 자동화 툴을 제작하게 되었습니다.

 

실제 엔진프로그래머가 있다면 훨씬 쉽게 제작 할 수 있는내용이나 엔진프로그래머가 없었던 시점이라 직접 블루프린트와 외부 플러그인 몇가지를 이용해 필요한 내용을 만들게 되었습니다.

 

이 기능을 만든 시점이 약 19년도쯤이라 설명상 틀린 내용이 있을 수 있습니다 ㅠ^ㅠ

 

3d케릭터를 스프리트이미지화 하는것은 게임에 사용하기로한 각도만큼 매애니매이션 프레임당 스크린샷을 찍는작업을 반복해야하며 4방향이라고 생각하면 1프레임당 4번의 스크린샷 을 찍어야 합니다.(매프레임 좌우상하)

 

결국 해야할 일은

1프레임

   좌 - 스크린샷 찍기 - 이름 바꾸기(a_좌_01)

   우 - 스크린샷찍기 - 이름 바꾸기(a_우_01)

   상 - 스크린샷 찍기 - 이름 바꾸기(a_상_01)

   하 - 스크린샷 찍기 - 이름 바꾸기(a_하_01)

2프레임

   좌 - 스크린샷 찍기 - 이름 바꾸기(a_좌_02)

   우 - 스크린샷찍기 - 이름 바꾸기(a_우_02)

   상 - 스크린샷 찍기 - 이름 바꾸기(a_상_02)

   하 - 스크린샷 찍기 - 이름 바꾸기(a_하_02)

.

.

.

.

60프레임

   좌 - 스크린샷 찍기 - 이름 바꾸기(a_좌_60)

   우 - 스크린샷찍기 - 이름 바꾸기(a_우_60)

   상 - 스크린샷 찍기 - 이름 바꾸기(a_상_60)

   하 - 스크린샷 찍기 - 이름 바꾸기(a_하_60)

 

이런식의 매우 반복되는 작업이기고 순차적인부분이 많아 충분히 자동화 할 수 있다고 생각했습니다

 

작업하면서 나오는 노드나 코딩방식은 아주아주 단순합니다 단순히 두번 루프를 돌리는 방법인데

주로 해야했던일들은

실제로 카메라를 어떻게 돌아가면서 배치하고 어떻게 파일이름을 저장할것인지

에디터 상에서 손으로 하듯이 한프레임씩 어떻게 밀어줄것인지

스크린 샷 캡쳐를 어떤방식으로 찍어서 알파를 자연스럽게 빠지게 할것인지

등 엔진에 이미 있거나 있을것 같은 기능들을 실제로 노드나 콘솔 명령어로 실행하는 방법을 찾는 일이었습니다.

 

특히 콘솔명령어로 스크린샷을 찍는부분은 설명도 없고 일일히 하나씩 해보며 해야되는 부분이었습니다.

 

시작

 

3개의 블루프린트 및 시퀀스 액터를 작성하게 됩니다.

 

1. 카메라 위치 설정 액터

2. 애니매이션을 실행할 레벨시퀀서

3. 실제로 시퀀스 프레임을 밀고 스크린샷을 찍는 명령어를 내릴 블루프린트(레벨 블루프린트)

 

1. 카메라 위치 설정 액터

일단 카메라의 위치를 지정할수 있도록 카메라 배열이 달린 액터를 제작합니다.

위 카메라중 2개는 미사용으로 처리를 해서 위치 설정이 되지 않았습니다.(4방향만 사용)

카메라 배열을 추가하면 더 많은 각도를 처리 가능합니다.

이런식으로 카메라의 각도나 상하 각도 / 거리 등을 한번에 제어해서 정확한 위치에 배치할 수 있도록 제공합니다.

이제 이 카메라 포지션을 레벨에 배치합니다.

 

 

2. 애니매이션을 실행할 레벨시퀀서

이제 실제로 찍힐 메쉬와 애니매이션을 등록할 레벨 시퀀서가 필요합니다.

별다른건 없고 일반 레벨시퀀서를 만들고 레벨에 미리 배치해 둡니다

screenshot_cam 이라고 명시된 카메라는 일반카메라이며 미리 배치된 상태입니다.

그 하단에 스켈레탈메쉬와 애니매이션을 등록합니다.

 

여기까지하면

레벨에 카메라의 포지션을 설정할 액터와 시퀀스액터 그리고 스켈레탈 메쉬 액터까지 등록이 될것입니다.

이런 느낌으로

이제 필요한 에셋들은 배치가 끝낫으니 레벨블루프린트에서 실제 작업할 내역을 작성합니다.

레벨블루프린트에서는 정해진 각도에 카메라를 위치하고 스크린샷을 찍고 파일이름을 지정해서 저장한뒤 1프레임 뒤로 밀고 다시 스크린샷을 찍게됩니다.

 

파일 이름을 저장하는 기능기 포함된 무료 플러그인이 있으니 받아줍니다.

ramaplugin 혹은 victoryplugin 이라는 이름으로 검색하면 쉽게 찾을 수 있습니다.

https://forums.unrealengine.com/t/39-ramas-extra-blueprint-nodes-for-you-as-a-plugin-no-c-required/3448

 

(39) Rama's Extra Blueprint Nodes for You as a Plugin, No C++ Required!

Dear Community, 🌟 Newest Awesome Feature 🌟 (In this Complimentary (no cost) Victory Plugin!) Now You Can Get the Text Output (STDOUT or STDERR) from any .exe program, straight into Unreal Engine! This is the output of ⚡ a video compression commandl

forums.unrealengine.com

위 버전이 맞는지 모르겠지만 맞는 버전이나 혹은 풀소스코드를 받아서 사용하셔도 됩니다 

 

위그림에서 루트 디렉토리를 찾아주는 기능과 저장할 위치를 설정해주는 등의 파일 이름 재설정 관련 기능은 victory 플러그인에 포함되어 있습니다.

그외에 카메라 액터에서 설정한 변수등을 다시 레벨 블루프린트에서 사용할 수 있도록 설정해줍니다.

뷰 포트 사이즈를 참조하므로 뷰포트는 1개만 사용해 줍니다.

 

세부사항은 다시 설명하겟지만 큰 흐름은 이렇습니다.

1번에서 현재 어떤각도를 찍어야 하는지 확인후 2번에서 카메라 위치에 정렬시킵니다.

그뒤에 루프a 구간으로 들어가서 총프레임만큼 1프레임씩 넘기면서 스크린샷을 찍어줍니다.

한 각도의 총 스크린샷을 다 찍게되면 다음 각도로 넘어가서(루프 b) 다시 루프 a 구간으로 넘어가서 매프레임 스크린샷을 따줍니다.

이렇게 계속 돌면서 정해진 각도를 다 수행하고 나면 exit로 나가서 종료하게됩니다.

 

위 이미지의 1- 2 구간입니다. 

 

1구간은 현재 찍어야하는 카메라(각도)의 총갯수보다 현재 카메라 인덱스가 적을시 루프를 진행하고 총갯수와 인덱스가 같으면 전부 찍었다고 결정하고 작업을 종료하는 부분입니다.

 

2구간은 카메라 인덱스에 따라서 카메라 배열(맨처음 제작한 카메라가 여럿 달린 액터에서 설정)에서 로케이션을 가져와 실제 캡쳐 할 카메라에 위치를 설정해줍니다.

또한 카메라의 배열에서 이름을 가져옵니다(이부분은 이미지 이름을 저장할때 각도부분에 씌이게 됩니다)

 

루프1의 시작부위입니다 최대한 이미지 안에 포함시키기 위해 노드들의 위치를 조금씩 변경햇습니다.

루프 조건은 현재 프레임(최초 0)부터 1씩 더해프레임 번호를 만들고 그 프레임으로 시퀀스의 타임바를 건너뛰게 하는것입니다. 이미지 우측 끝 딜레이는 앞선 프레임에서 찍은 캡쳐가 하드디스크에 저장되는 시간이 필요해 딜레이를 주게됩니다 

노드자체는 매우 단순한 루프 구조입니다.

단지 자주 사용되지 않는 프레임 넘버 만들기 jump to 등이 포함되어 있기에 방법만 알면 쉽게 만들수 있습니다.

 

이제 이미지의 이름을 만들고(사전 접두어 +카메라각도+현재 프레임) 콘솔명령어로 스크린샷을 찍습니다.

 

' HighResShot 1 X 1, viewsize_X, viewsize_Y, 1 '

이며 오래되서 정확히 기억나지는 않지만 1x1은 생성될 이미지 비율, 뒤에 캡쳐를 할 영역크기, 1은 캡쳐할 방식이었던 것같습니다

 

이렇게 스크린샷을찍게되면 마스킹된 캡쳐를 찍을 수 있습니다.

맨마지막 ,1 쪽을 조절하면 찍고 싶은 채널을 조절할 수 있고 알파 블렌드가 필요하다면 알파 블렌드 채널도 뽑을 수 있었던 것으로 기억합니다.

 

이런식으로 매프레임 이동하면서 스크린 샷을 찍고 지정된 폴더에 정해진 이름으로 자동적으로 저장하게 됩니다.

 

실제로 스크린샷을찍는방법은

1. 레벨 시퀀스 에디터를 엽니다.

2. 레벨 시퀀스 카메라를 뷰포트에 바인딩 합니다.

3. 시물레이트 모드로 레벨을 플레이 합니다.

이렇게 시뮬레이트 모드로 플레이를 하게되면 자동적으로 스크린샷을찍고 완료되면 완료 로그를 남기게 됩니다.

요렇게 에디터 창을 열고 카메라가 뷰포트에 바인딩 되어 있는 상태로 실행하면 됩니다

 

문의점이나 궁굼하신건 댓글이나 쪽지 남겨주세요