🎮Unreal4/Blueprint

[UE4] Decal(데칼), 커서(Cursor) 이미지 3D 월드에 출력, Get Hit Result Under Cursor by Channel, SetWorldLocationAndRotation, RotationFromXVector

공대 컴린이 2023. 2. 4. 15:57
728x90

마법사의 순간이동 기능을 구현하던 도중, 어느 지점으로 순간이동 해야할지 마우스 커서를 출력하는 기능을 구현해보았다.

🎨 Decal (데칼)

Decal은 화면 공간에 텍스처를 그릴 수 있도록 도와주는 컴포넌트이다. 예를 들어 마법진이나, 문신같이 게임 속에 그림/이미지를 그려야하는 경우 사용된다.

언리얼 문서에서는 레벨의 메시에 투영되는 머티리얼로, 스태틱 메시나 스켈레탈 메시 등에 투영되는 컴포넌트를 말한다고 쓰여있다.

 

Decal 컴포넌트 삽입

나는 플레이어의 순간이동 지점을 표시할 마법진을 그리기 위해 Decal 컴포넌트를 추가하였고, 바닥에 출력하기 위해 트랜스폼을 적절하게 조절하였다.

이후 디테일 패널에서 Decal 카테고리의 Decal Material 항목에 출력할 머티리얼을 설정해주었다. 

 

Cursor Material

나는 M_Cursor라는 쉐이더 코드로 작성되어 두개의 원형 테두리가 출력되는 Material 파일을 이용하였다.

 

이처럼 데칼의 머티리얼까지 모두 설정하고 나면 출력될 지점과 순간을 설정해주어야 한다.

 

Warp 무기를 구현하는 Weapon_Warp 블루프린트 클래스

커서도 결국은 3D 공간의 카메라 영역에서 출력되기 때문에 Character의 Get Controller를 가져와서 PlayerController 변환 과정을 수행해준다.

이후 게임이 플레이 된 순간은 데칼이 보이지 않도록 Set Visibility를 False로 설정한 뒤, 특정 액션값(무기 장착)을 받으면 출력되도록 구현하였다.

 

데칼이 성공적으로 출력되고 나면, 원점(0,0,0)에 출력되는 데칼을 마우스 커서가 움직임을 따라올 수 있도록 Location과 Rotation을 조절해줘야 한다.

 

이를 구현하기 위해 Get Cursor Location and Rotation 함수를 작성하였다.

💡 Get Cursor Location and Rotation 함수 (사용자 정의 함수)

Weapon_Warp의 Get Cursor Location and Rotation 함수

플레이어 컨트롤러가 있어야 카메라 공간으로 변환될 수 있기에 변수로 저장해둔 Player Controller를 가져오고, 컨트롤러 안에 존재하는 Get Hit Result 함수를 호출하였다.

 

(이때 Impact Normal 벡터를 RotationFromXVector 함수로 변환하는 과정이 매우 중요한데 이는 뒤에서 설명한다.)

💡 Get Hit Result Under Cursor by Channel 함수

Get Hit Result 함수는 크게 Cursor 와 Finger 의 두 종류로 분리된다.

Cursor 함수는 마우스 커서를 나타내고, Finger 함수는 손가락 터치를 의미한다. 

  • Get Hit Result Under Cursor by Channel (채널별로 커서 아래 적중 결과 얻기)
    마우스 커서 아래에 위치하는 콜리전 쿼리를 수행하며, 트레이스 채널을 살펴본다.
  • Get Hit Result Under Cursor by Objects
    마우스 커서 아래에 위치하는 콜리전 쿼리를 수행하며, 오브젝트 유형을 찾는다.
  • Get Hit Result Under Finger by Channel
    손가락 아래에 위치하는 콜리전 쿼리를 수행하며, 트레이스 채널을 살펴본다.
  • Get Hit Result Under Finger by Objects
    손가락 아래에 위치하는 콜리전 쿼리를 수행하며, 오브젝트 유형을 찾는다.

Trace Channel이 Visibility라는 의미는 화면에 보이는 모든것을 의미한다. 

해당 함수의 Hit Result에 Break Hit Result 함수를 호출하여 충돌된 결과 정보들의 구조체를 전달 받았고, 해당 결과 중 Blocking Hit(커서와 충돌된 객체)가 있으면 충돌 객체의 Location과 Rotation을 모두 반환해주었고, Blocking Hit가 없다면 Zero 정보를 반환해주었다. 

(참고, Get Hit Result 함수는 Trace 기반 함수여서 결과값이 Trace System 요소들이 나온다)

 

Weapon_Warp 블루프린트 클래스

작성된 Get Cursor Location and Rotation 함수를 Tick 이벤트에서 호출해주었고, 반환되는 Hit 값이 있다면 Decal의 Visibility를 True로 설정해주었다.

마지막으로 Hitting 된 위치로 Decal을 옮겨주기 위해 SetWorldLocationAndRotation 함수를 호출하였다.

💡 SetWorldLocationAndRotation 함수

SetWorldLocationAndRotation 함수는 컴포넌트가 상대간격인데, 타깃으로 들어온 액터의 현재 간격을 부모와 계산한 다음에 최종 액터의 위치와 결합하여 World 위치로 만들어주는 함수이다.

언리얼 문서에서는 구성 요소의 상대 위치 및 회전을 설정하여 월드 공간에서 제공된 포즈에 배치한다고 적혀있다.

💡 Impact Normal 벡터를 RotationFromXVector 함수로 변환

Get Cursor Location And Rotation함수를 만들 때 반환되는 Rotation 값에 Impact Normal 벡터를 RotationFromXVector 함수로 변환하는 단계를 거쳐 전달해주었다.

 

Rotation 조정 전 출력 결과 (비정상 출력)

이 과정을 거치지 않으면 Decal이 출력될 때 회전이 들어가지 않아서 정면 벽 방향에 출력되는 것이 아니면 이상하게 출력된다.

 

트레이스에 무언가가 걸릴 때 "Hit Result"를 반환하는데 Hit 결과 분해 값에서 Impact라고 적혀있는 Impoct Normal과 Impact Point는 충돌체를 의미한다. 여기서 Normal은 노멀벡터를 의미한다. (노멀벡터를 어떻게 구하는지는 다음에 설명함)

 

그냥 Normal과 Impact Normal의 차이는 정밀한 연산을 수행하는지의 여부이다. 

Normal은 메시에 그려지는 삼각형들의 노멀값을 구한 결과이고, Impact Normal은 충돌체 표면을 나타낸 것이다.

따라서 메시를 이루는 삼각형 하나하나의 노멀값을 구하는 Normal은 정확한 회전값을 낼 수있어 정밀한 연산이 필요한 경우에 사용하고, Impact Normal은 정밀할 필요 없이 표면에 관한 큼직큼직한 회전을 구현할 때 사용된다.

 

따라서 이번 Decal을 구현할 때 Decal이 출력될 위치는 정밀해야 하므로 Impact Point가 아닌 Location을 사용하고, 회전은 정밀할 필요가 없으므로 Impact Normal을 사용하였다.

💡 RotationFromXVector

ImpactNormal을 끌어서 반환 노드에 Rotation으로 연결하면 자동으로 RotationFromXVector가 생성된다.

RotationFromXVector는 X축을 기준으로 한 노멀에 대한 회전값을 도출한다. 즉, 벡터가 가리키는 방향에 해당하는 FRotator 방향을 반환하는 것이다. 


참조

https://docs.unrealengine.com/4.27/ko/Resources/ContentExamples/Decals/

 

데칼

Decals 예제 레벨에 대한 개요입니다.

docs.unrealengine.com

https://docs.unrealengine.com/4.27/ko/Resources/ContentExamples/Decals/1_1/

 

1.1 - 기본 데칼

Decal 예제 레벨에 대한 개요로, 예제 1.1: Basic Decal, 기본 데칼 입니다.

docs.unrealengine.com

https://docs.unrealengine.com/5.0/en-US/BlueprintAPI/Transformation/SetWorldLocationAndRotation/

 

Set World Location And Rotation

Set World Location And Rotation

docs.unrealengine.com

https://docs.unrealengine.com/5.0/en-US/BlueprintAPI/Game/Player/GetHitResultUnderCursorbyChannel/

 

Get Hit Result Under Cursor by Channel

Get Hit Result Under Cursor by Channel

docs.unrealengine.com

https://docs.unrealengine.com/4.27/ko/InteractiveExperiences/Tracing/Overview/

 

트레이스 개요

언리얼 엔진 4 의 트레이스 시스템 개요입니다.

docs.unrealengine.com

 

728x90