언리얼 5

230919 StartMap - StartGameMode / StarHUD_Base | NewMap - SceneCapture2DComponent

슬뷔 2023. 9. 19. 10:49

AStartGameMode 을 상속받아서 StartGameMode 생성

 

기본 default 상태가 게임모드 -> 마우스가 사라지고 캐릭터를 조작하는데 집중

UI 모드 -> 캐릭터의 input 이 전혀 동작하지 않는다

 

즉, StartMap 은 Pawn 도 없고 캐릭터가 필요없기 때문에 UI 모드로 지정.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "../Header/global.h"

#include "../UI/StartHUD_Base.h"

#include "StartGameMode.generated.h"

UCLASS()
class UNREAL_3TH_API AStartGameMode : public AGameModeBase
{
	GENERATED_BODY()
private:
	TSubclassOf<UStartHUD_Base> m_StartHUDClass;
	UStartHUD_Base* m_StartHUD;

public:
	virtual void BeginPlay() override;

public:
	AStartGameMode();
	~AStartGameMode();
};
#include "StartGameMode.h"

AStartGameMode::AStartGameMode()
{
	ConstructorHelpers::FClassFinder<UUserWidget> StartHUDFind(TEXT("/Script/UMGEditor.WidgetBlueprint'/Game/BlueprintClass/UMG/HUD/StartHUD.StartHUD_C'"));

	if (StartHUDFind.Succeeded())
	{
		m_StartHUDClass = StartHUDFind.Class;
	}
}

AStartGameMode::~AStartGameMode()
{
}

void AStartGameMode::BeginPlay()
{
	m_StartHUD = Cast<UStartHUD_Base>(CreateWidget(GetWorld(), m_StartHUDClass));

	if (!IsValid(m_StartHUD))
	{
		LOG(LogTemp, Error, TEXT("StartHUD 생성 실패"));
	}

	else
	{
		m_StartHUD->AddToViewport();
	
		// UI 모드로 전환
		APlayerController* pController = GetWorld()->GetFirstPlayerController();

		FInputModeUIOnly uimod;
		pController->SetInputMode(uimod);

		// 화면에 마우스 보이게 하기
		pController->bShowMouseCursor = true;
	}

}

UUserWidget을 상속받아서 StarHUD_Base 생성

#include "Components/Button.h"

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "StartHUD_Base.generated.h"

UCLASS()
class UNREAL_3TH_API UStartHUD_Base : public UUserWidget
{
	GENERATED_BODY()

private:
	UButton*	m_StartBtn;
	UButton*	m_EndBtn;

public:
	virtual void NativeConstruct() override;
	virtual void NativeTick(const FGeometry& _geo, float _DT) override;

public:
	UFUNCTION()
	void StartBtnClicked();

	UFUNCTION()
	void EndBtnClicked();
};

 

#include "StartHUD_Base.h"

#include "../Header/global.h"

void UStartHUD_Base::NativeConstruct()
{
	m_StartBtn = Cast<UButton>(GetWidgetFromName(FName("StartBtn")));
	m_EndBtn = Cast<UButton>(GetWidgetFromName(FName("EndBtn")));

	if (!IsValid(m_StartBtn) || !IsValid(m_EndBtn))
	{
		LOG(LogTemp, Error, TEXT("버튼 참조 실패"));
	}
	else
	{
    		// Delligate
		m_StartBtn->OnClicked.AddDynamic(this, &UStartHUD_Base::StartBtnClicked);
		m_EndBtn->OnClicked.AddDynamic(this, &UStartHUD_Base::EndBtnClicked);
	}
}

void UStartHUD_Base::NativeTick(const FGeometry& _geo, float _DT)
{

}


void UStartHUD_Base::StartBtnClicked()
{
	LOG(LogTemp, Warning, TEXT("Start Button Clicked"));
}

void UStartHUD_Base::EndBtnClicked()
{
	LOG(LogTemp, Warning, TEXT("End Button Clicked"));
}

 

위젯 애니메이션

 

class UNREAL_3TH_API UStartHUD_Base : public UUserWidget
{
	GENERATED_BODY()

private:
	UButton*	m_StartBtn;
	UButton*	m_EndBtn;

public:
	virtual void NativeConstruct() override;
	virtual void NativeTick(const FGeometry& _geo, float _DT) override;

public:
	UFUNCTION()
	void StartBtnClicked();
	UFUNCTION()
	void StartBtnHovered();
	UFUNCTION()
	void StartBtnUnHovered();

	UFUNCTION()
	void EndBtnClicked();
	UFUNCTION()
	void EndBtnHovered();
	UFUNCTION()
	void EndBtnUnHovered();
}
#include "StartHUD_Base.h"

#include "../Header/global.h"
#include "Blueprint/UserWidget.h"

void UStartHUD_Base::NativeConstruct()
{
	Super::NativeConstruct();

	m_StartBtn = Cast<UButton>(GetWidgetFromName(FName("StartBtn")));
	m_EndBtn = Cast<UButton>(GetWidgetFromName(FName("EndBtn")));

	if (!IsValid(m_StartBtn) || !IsValid(m_EndBtn))
	{
		LOG(LogTemp, Error, TEXT("버튼 참조 실패"));
	}
	else
	{
		m_StartBtn->OnClicked.AddDynamic(this, &UStartHUD_Base::StartBtnClicked);
		m_StartBtn->OnHovered.AddDynamic(this, &UStartHUD_Base::StartBtnHovered);
		m_StartBtn->OnUnhovered.AddDynamic(this, &UStartHUD_Base::StartBtnUnHovered);

		m_EndBtn->OnClicked.AddDynamic(this, &UStartHUD_Base::EndBtnClicked);
		m_EndBtn->OnHovered.AddDynamic(this, &UStartHUD_Base::EndBtnHovered);
		m_EndBtn->OnUnhovered.AddDynamic(this, &UStartHUD_Base::EndBtnUnHovered);
	}
}

void UStartHUD_Base::StartBtnHovered()
{
	LOG(LogTemp, Warning, TEXT("Start Button Hovered"));

	// 애니메이션 정보를 가져온다
	// 배열이라서 순차탐색을 해야한다
	UWidgetBlueprintGeneratedClass* pWidgetClass = GetWidgetTreeOwningClass();
	for (int32 i = 0; i < pWidgetClass->Animations.Num(); ++i)
	{
		// 실제이름과 다르게 뒤에 _INST 를 붙여주어야한다.
		if (pWidgetClass->Animations[i].GetName() == TEXT("StartBtnHoveredAnim_INST"))
		{
			PlayAnimation(pWidgetClass->Animations[i]);
			break;
		}
	}
}

void UStartHUD_Base::StartBtnUnHovered()
{
	UWidgetBlueprintGeneratedClass* pWidgetClass = GetWidgetTreeOwningClass();
	for (int32 i = 0; i < pWidgetClass->Animations.Num(); ++i)
	{
		if (pWidgetClass->Animations[i].GetName() == TEXT("StartBtnUnHoveredAnim_INST"))
		{
			PlayAnimation(pWidgetClass->Animations[i]);
			break;
		}
	}
}

결과

void UStartHUD_Base::StartBtnClicked()
{
	LOG(LogTemp, Warning, TEXT("Start Button Clicked"));

	UGameplayStatics::OpenLevel(GetWorld(), TEXT("NewMap"));
}

void UStartHUD_Base::EndBtnClicked()
{
	LOG(LogTemp, Warning, TEXT("End Button Clicked"));

	// end 버튼을 눌렀을 때, 종료되게 설정
	UKismetSystemLibrary::QuitGame(GetWorld()
				, GetWorld()->GetFirstPlayerController()
				, EQuitPreference::Quit
				, true);
}

결과

*  아래를 해주지 않으면 start 눌렀을 때, 뉴맵으로 가면서 ui모드가 계속 진행되어 플레이어 인풋이 안 먹히는 현상이 발생한다.

void AUnreal_3thGameModeBase::BeginPlay()
{
	Super::BeginPlay();

	// Game 모드로 전환
	APlayerController* pController = GetWorld()->GetFirstPlayerController();

	FInputModeGameOnly gamemod;
	pController->SetInputMode(gamemod);
	pController->bShowMouseCursor = false;
}

PlayerInfo 의 캐릭터 사진을 카메라가 바라보는 장면으로 설정 ( 초록색 네모박스 부분 )

BPC_Player_C 에서 씬 캡쳐 컴포넌트 2D (Capture2D) 생성 

=> 랜더타겟텍스쳐만 목적지(송출지)로 삼을 수 있다

=> RT_Character 생성

* 머테리얼 도메인 -> User Interface 로 변경

캡처소스를 SceneColor in RGB, SceneDepth in Arpha 로 하면 재질에서 이를 활용할 수 있다

(카메라 시점자로부터 그리고 있는 물체가 얼마나 떨어져 있었는지 거리값을 알파에 기록)

 

* SceneColor in RGB, SceneDepth in Arpha -> 화면 색상은 RGB, 카메라로부터의 거리값은 픽셀단위로 A에 넣는다

 

깊이를 충분히 저장할 수 있게끔 RT_Character의 랜더타깃 포맷을 바꿔준다

머테리얼 (MT_Character) 생성해서 씬 캡쳐가 보는 화면을 UI 로 전송한다

뒷배경 안나오고 플레이어만 나오게 하기

이렇게 했더니 캐릭터를 제외한 배경은 까맣게 나오게된다.

뒷 배경 변경하기

렌더타겟과 배경이미지가 될 2개의 텍스쳐를 가져와서 혼합
if 문을 통해 깊이 값이 500이하인 부분은 캐릭터 렌더타겟부분을 사용하고, 그 외부는 배경쪽을 사용하도록 혼합하는 수식을 작성한다

결과

 

 

'언리얼 5' 카테고리의 다른 글

230921 인벤토리 설비 및 아이템 설비  (0) 2023.09.21
230920 몬스터 체력바 / 인벤토리  (0) 2023.09.20
230918 위젯  (0) 2023.09.18
230915 몬스터 AI - Trace, Attack ( 스스로 )  (0) 2023.09.15
230914 몬스터 AI - Move  (0) 2023.09.15