이전 글 보기
https://mountain-noroo.tistory.com/67
툴팁
언리얼에서는 위젯에 마우스를 호버 했을 시에 툴팁을 보여주는 기능도 제공한다.
// Tooltip_Base 를 상속받은 Tooltip Blueprint 클래스정보 가져오기
UBlueprintGeneratedClass* TooltipClass = LoadObject<UBlueprintGeneratedClass>(nullptr, TEXT("/Script/UMGEditor.WidgetBlueprint'/Game/BlueprintClass/UMG/Inventory/Tooltip.Tooltip_C'"));
if (IsValid(TooltipClass))
{
// Blueprint 클래스정보로 실제 객체하나 만들어서 ListView 의 Tooltip 용으로 전달하기
m_ListView->SetToolTip(CreateWidget(GetWorld(), TooltipClass));
// 리스트뷰 항목(아이템) 위로 마우스가 올라가거나 벗어날 때 호출될 함수 바인딩
m_ListView->OnItemIsHoveredChanged().AddUObject(this, &UInventory_Base::OnHovered);
}
ListView에서 ToolTip용 위젯을 추가하고, 호버 되거나 벗어날 때 호출되는 함수를 바인딩할 수 있다.
인벤토리의 NativeConstruct에 추가한다.
NativeConstruct는 초기화 시 호출되는 함수이지 엄밀히 말해 생성자는 아니기 때문에 ConstructorHelpers는 사용하지 못하고 LoadObject로 클래스 정보를 가져와야만 한다.
SetToolTip 함수는 매개변수로 UBlueprintGeneratedClass* 타입을 받는다.
AddUObject 델리게이트와 AddDynamic 델리게이트의 차이는 블루프린트에서 사용할 수 있느냐 없느냐의 차이
실제로 AddUObject를 등록할 때는 UFUNCTION 매크로를 사용하지 않아도 된다.
void UInventory_Base::OnHovered(UObject* _Data, bool _hovered)
{
if (_hovered)
{
// 마우스 호버한 아이템 위젯과 연결되어있는 데이터 가져옴
UInvenItemData* pData = Cast<UInvenItemData>(_Data);
// ListView 에 넣어둔 툴팁용 위젯 객체 가져옴
UTooltip_Base* pTooltip = Cast<UTooltip_Base>(m_ListView->ToolTipWidget);
// 툴팁 위젯의 TextBlock 에 Item Description 정보 문자열 전달
pTooltip->GetTextBlock()->SetText(FText::FromString(pData->GetItemDescription()));
// 툴팁 위젯 시각화
m_ListView->ToolTipWidget->SetVisibility(ESlateVisibility::Visible);
}
else
{
m_ListView->ToolTipWidget->SetVisibility(ESlateVisibility::Hidden);
}
}
호버되었을 때 툴팁 위젯의 TextBlock에 아이템 설명을 전달해 주는 기능을 넣었다.
마우스
하드웨어 마우스: 별 다른 기능 없이 일반 마우스에 스킨을 입혀 사용한다.
경로는 콘텐츠 폴더 기준으로 작성한다.
핫스팟은 마우스 클릭의 중심이 되는 좌표로 기본 좌상단(마우스의 뾰쪽한 곳)이다.
소프트웨어 마우스: 위젯을 마우스로 설정 가능하다. 기능을 직접 추가할 수 있다.
일반 위젯을 추가할 수 있다.
핫스팟 기능이 여기엔 없는데 대신 위젯 안에서 커서 이미지의 오프셋을 바꾸면 된다.
C++ 코드에서 마우스 설정하기
AMyPlayerController::AMyPlayerController()
{
CurrentMouseCursor = EMouseCursor::Default;
bShowMouseCursor = true;
bEnableClickEvents = true;
bEnableMouseOverEvents = true;
}
void AMyPlayerController::BeginPlay()
{
TSubclassOf<UUserWidget> pDefault = LoadClass<UUserWidget>(GetWorld(), TEXT("/ Script / UMGEditor.WidgetBlueprint'/Game/BlueprintClass/UMG/Mouse/Mouse.Mouse_C'"));
TSubclassOf<UUserWidget> pGrapHand = LoadClass<UUserWidget>(GetWorld(), TEXT("/ Script / UMGEditor.WidgetBlueprint'/Game/BlueprintClass/UMG/Mouse/Mouse_GrabHand.Mouse_GrabHand_C'"));
SetMouseCursorWidget(EMouseCursor::Default, CreateWidget(GetWorld(), pDefault));
SetMouseCursorWidget(EMouseCursor::GrabHand, CreateWidget(GetWorld(), pGrapHand));
}
C++ 코드에서도 마우스 커서를 설정할 수 있다.
이는 PlayerController 클래스에서 이루어진다.
생성자에서 이벤트를 사용할 수 있도록 bEnableClickEvents, bEnableMouseOverEvents를 활성화해주고
마우스를 보이도록 bShowMouseCursor도 활성화해 준다.
그리고 생성자 시점에서는 아직 언리얼 내부에서 커서에 대한 초기화 작업이 이루어지지 않았기 때문에
BeginPlay에서 LoadClass를 이용해 마우스 위젯을 가져와
SetMouseCursorWidget(EMouseCursor(마우스 상태) enum, UUserWidget)를 호출해 마우스 커서로 설정해주어야 한다.
소프트웨어 마우스에 여러 기능을 구현할 수 있는데
한 가지 예시로 몬스터 위에 마우스를 놓았을 시에 모양이 바뀌도록 할 수 있다.
void AMyPlayerController::Tick(float _DT)
{
Super::Tick(_DT);
// 플레이어 컨트롤러에서 매 틱마다 마우스 위치로 RayCasting 시도
// TraceChannel 은 PlayerAttack 채널 사용
FHitResult result = {};
bool bHit = GetHitResultUnderCursor(ECC_GameTraceChannel5, false, result);
// 마우스 방향 Ray Check 에 걸린 대상이 있다면
if (bHit)
{
// 걸린 대상이 몬스터 타입이면
if (Cast<AMonster_Base>(result.GetActor()))
{
// 현재 마우스 상태를 GrabHand 로 변경
CurrentMouseCursor = EMouseCursor::GrabHand;
}
else
{
// 충돌 중인 오브젝트가 없다면 항상 Default 상태로 둠
CurrentMouseCursor = EMouseCursor::Default;
}
}
else
{
// 충돌 중인 오브젝트가 없다면 항상 Default 상태로 둠
CurrentMouseCursor = EMouseCursor::Default;
}
}
구현 방법은 여러 가지가 있는데 여기에서는 마우스 방향으로 레이캐스트 연산을 매 틱마다 실행하여 채널에 걸리는 것이 있고, 그것이 몬스터 타입이라면 마우스 상태를 바꾸는 방법을 사용하였다.
플레이어 컨트롤러를 상속받아 Tick에서 구현하였다.
이건 블루프린트에서 더 쉽게 할 수 있는데
액터 블루프린트에서 ActorBeginCursorOver, ActorEndCursorOver이라는 이벤트를 지원해 주기 때문에
SetCurrentMouseCursor노드를 가져와서 커서를 변경해 줄 수 있다.
AMyPlayerController::AMyPlayerController()
{
bEnableMouseOverEvents = true;
}
이 이벤트를 동작하게 하려면 플레이어 컨트롤러에서 bEnableMouseOverEvents를 켜줘야만 한다.
레이캐스트 연산은 많은 비용이 들기 때문에 다른 방법을 사용하는 것을 추천한다.
위젯 위에 마우스를 올렸을 때 상태를 바꾸게 하려면
캔버스패널에서 커서를 검색해 Enable 하고 원하는 상태로 변경해 주면 된다.
빌보드
계속 정면을 바라보게 만들어주는 컴포넌트.
Billboard Component와 Material Billboard Component 두 가지가 있는데, 후자는 머터리얼을 직접 설정해 줄 수 있다는 차이가 있음.
스프라이트에서 추가.
그래픽스 파이프라인
Object Space(=Local Space, Model Space)
기본적으로 메시 에셋의 정점은 메시 기준의 원점(주로 발)으로부터 정점의 좌표로 나타내져 있다. 이 메시 에셋의 원점 기준의 좌표계를 Object Space(또는 Local, Model Space)라고 한다.
메시 정보(원본 에셋)는 메모리상에 하나 존재하고, 이를 몬스터의 위치에 옮겨서 사용한다.
World Space
월드에도 원점이 존재한다. 메시의 버텍스들을 전부 월드의 원점을 기준으로 옮긴다.
(100, 100)의 위치로 옮긴다고 하면 모든 정점에 x 100, y 100을 더해주는 것이다.
Camera Relative World Space(WS)
그리고 결국 목표는 우리가 보는 화면을 그리는 것이기 때문에 카메라의 기준으로 좌표계를 변경해주어야 한다.
Camera Relative World Space는 언리얼에만 있다.
언리얼은 특이하게 X가 깊이, Z가 높이, Y가 오른쪽 방향인 좌표계를 사용하기 때문이다.
Camera Space (ViewSpace)
일반적인 좌표계인, Z가 깊이, Y가 높이, X가 오른쪽 방향인 좌표계로 변환한다.
작은 사각형 상에 카메라에서 바라본 대로 기록한다.
X, Y 픽셀의 색상값을 기록하고 깊이 값 또한 따로 기록한다.
이 픽셀에 픽셀 쉐이더를 적용하여 보이게 된다.
UV
uv좌표는 좌상단 0, 0 우하단 1,1로 되어있는 2차원 좌표계이다.
가로축을 u 세로축을 v라고 한다.
텍스처의 좌표계로 u, v를 사용한다.
원래 정점에 매핑된 uv 좌표를 가져와서 텍스처의 해당 좌표 색상 값을 입혀준다.
버텍스 사이의 부분 또한 uv좌표 사이 보간된 색상 값이 들어가게 된다.
http://www.opengl-tutorial.org/kr/beginners-tutorials/tutorial-3-matrices/
이부분은 모든 것에 있어 가장 중요한 단 하나의 튜토리얼입니다. 그러니 최소한 여덟번은 읽도록 하세요.
'언리얼 > Assortrack UE5' 카테고리의 다른 글
[언리얼] 학원 23일차: Material (0) | 2023.09.27 |
---|---|
[언리얼] 학원 22일차: Material(ScreenUV, MRT(Deffered)) 활용 (0) | 2023.09.26 |
[언리얼] 학원 20일차: 인벤토리 끄기(UMG Input) (0) | 2023.09.22 |
[언리얼] 학원 19일차: 아이템 획득, 인벤토리 매니저 (0) | 2023.09.21 |
[언리얼] 학원 18일차: 액터 위 UI, 인벤토리(리스트) (0) | 2023.09.20 |