UserWidget c++ 구현후 HUD에 넣기.
유저인터페이스에서는 여러가지 기능을 사용하기 위해서는 빌드cs파일에 모듈명을 넣어야 유저인터페이스 관련 기능들을 사용할수가 있다.
https://docs.unrealengine.com/4.27/en-US/API/Runtime/UMG/Blueprint/UUserWidget/
UUserWidget
The user widget is extensible by users through the WidgetBlueprint.
docs.unrealengine.com
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "UMG" });
이렇게 모듈생성후 이제 인터페이스를 사용하는 방법은 다음과 같다.
먼저 widget c++클래스를 생서해준다.
저같은 경우에는 Crosshair를 만들기 위해 Player_Crosshair_Widget이라 하여 다음코드를 만들겠습니다.
Player_Crosshair_Widget.h
UCLASS()
class PROJECT_API UPlayer_Crosshair_Widget : public UUserWidget
{
GENERATED_BODY()
public:
//생성시 호출됨//
virtual void NativeConstruct() override;
//플레이어의 줌인지를 하기위해서 함수를 하나 호출해줌//
void UpdateWidgetVisibility();
private:
//플레이어를 형변환받기 위해 변수를 선언//
//UPROPERTY(EditAnywhere, BlueprintReadWrite)
class AThirdPersonCharacter* Player;
public:
//하나의 이미지로 받아서 보이게 할수도 있지만 크로스헤어를 하나를 만들기위해 각 위치의
크로스헤어를 선언함//
UPROPERTY(meta = (BindWidget))
class UImage* Crosshair_top;
UPROPERTY(meta = (BindWidget))
class UImage* Crosshair_bottom;
UPROPERTY(meta = (BindWidget))
class UImage* Crosshair_left;
UPROPERTY(meta = (BindWidget))
class UImage* Crosshair_right;
};
(위젯 클래스의 오브젝트클래스들에 UPROPERTY에 meta가 아니 다른 지정자를 작성하면 가끔식 값이 안들어갈때도 있다.)
Player_Crosshair_Widget.cpp
void UPlayer_Crosshair_Widget::NativeConstruct()
{
// Call Blueprint Event Construct node
Super::NativeConstruct();
//플레이어의 정보를 가져다쓰기 위해 형변환을 할당해줌//
Player = Cast<AThirdPersonCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
}
void UPlayer_Crosshair_Widget::UpdateWidgetVisibility()
{
//할당한 플레이어변수의 줌인 : 줌아웃인지를 판단해 보이거나 숨기기를 함//
Player->bZoomIn ? SetVisibility(ESlateVisibility::Visible) : SetVisibility(ESlateVisibility::Hidden);
}
만약 UImage의 기능을 사용하고 싶으면 #include "Components/Image.h"를 사용하면 되지만 지금은 Userwidget과 hud의 기본적인것만 하기에 다음에 기능을 이용하여 총의 이미지나 이름을 가져와 위젯에 입히기를 하겠습니다.
https://docs.unrealengine.com/4.26/en-US/API/Runtime/UMG/Components/UImage/
UImage
The image widget allows you to display a Slate Brush, or texture or material in the UI.
docs.unrealengine.com
이렇게 구현이 완료되면 이제 HUD를 아래와 같이 생성해줍니다.
Player_HUD.h
#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
//크로스헤어 기능을 사용하기 위해 인클루드 해줌//
#include "Player_Crosshair_Widget.h"
#include "Player_HUD.generated.h"
/**
*
*/
UCLASS()
class PROJECT_API APlayer_HUD : public AHUD, public IWeapon_Interface
{
GENERATED_BODY()
public:
APlayer_HUD();
virtual void DrawHUD() override;
virtual void BeginPlay() override;
virtual void Tick(float DeltaSeconds) override;
//플레이어 크로스헤어 함수//
//플레이어 기능을 이용할 수 있도록 함수를 선언//
void UpdateWidgetVisibility();
public:
//HUD블루프린트에서 선택하여 블루프린트로 설정한 이미지를 띄울수 있도록 위젯클래스를 선언//
UPROPERTY(EditDefaultsOnly, Category = "Interactive")
TSubclassOf<UUserWidget> CrosshairWidgetClass;
private:
//클래스파일에서 설정한 기능을 사용할수 있도록 크로스헤어 변수를 선언해줌//
UPlayer_Crosshair_Widget* CrosshairWidget;
};
Player_HUD.cpp
APlayer_HUD::APlayer_HUD()
{
}
void APlayer_HUD::DrawHUD()
{
Super::DrawHUD();
}
void APlayer_HUD::BeginPlay()
{
Super::BeginPlay();
//블루프린트로 설정한 크로스헤어들은 플레이어 화면에 띄우고 기능을 같이 쓸수 있도록 생성해줌//
if (CrosshairWidgetClass)
{
//블루프린트의 이미지 설정을 넣어줌//
CrosshairWidget = CreateWidget<UPlayer_Crosshair_Widget>(GetWorld(), CrosshairWidgetClass);
if (CrosshairWidget)
{
//위젯을 화면에 띄움//
CrosshairWidget->AddToViewport();
}
}
}
void APlayer_HUD::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
}
//크로스헤어의 기능을 호출해줌//
void APlayer_HUD::UpdateWidgetVisibility()
{
if (CrosshairWidget) CrosshairWidget->UpdateWidgetVisibility();
}
이제 플레이어 캐릭터에서 사용할수 있도록 아래와 같이 추가해줌.
//!ThirdPersonCharacter.h//
//!HUD ref//
class APlayer_HUD* Player_HUD;
//!bZoomIn ref//
bool bZoomIn;
//!ZoomIn : ZoomOut Func//
void ZoomIn();
void ZoomOut();
//!ThirdPersonCharacter.cpp//
//!HUD 함수를 호출하기위해 include//
#include "Player_HUD.h"
void AThirdPersonCharacter::BeginPlay()
{
Super::BeginPlay();
//플레이어 HUD//
//HUD의 형변환을 위해 아래와 같이 선언해줌//
Player_HUD = Cast<APlayer_HUD>(GetWorld()->GetFirstPlayerController()->GetHUD());
}
void AThirdPersonCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//bZoomIn상태를 계속 확인하기위해 HUD의 함수를 호출해줌//
Player_HUD->UpdateWidgetVisibility();
}
void AThirdPersonCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
check(PlayerInputComponent);
InputComponent->BindAxis("MoveForward", this, &AThirdPersonCharacter::MoveForward);
InputComponent->BindAxis("MoveRight", this, &AThirdPersonCharacter::MoveRight);
InputComponent->BindAxis("Turn", this, &AThirdPersonCharacter::Turn);
InputComponent->BindAxis("LookUp", this, &AThirdPersonCharacter::LookUp);
InputComponent->BindAction("Jump", IE_Pressed, this, &AThirdPersonCharacter::JumpStart);
InputComponent->BindAction("Jump", IE_Released, this, &AThirdPersonCharacter::JumpEnd);
InputComponent->BindAction("Run", IE_Pressed, this, &AThirdPersonCharacter::RunStart);
InputComponent->BindAction("Run", IE_Released, this, &AThirdPersonCharacter::RunEnd);
InputComponent->BindAction("Crouch", IE_Pressed, this, &AThirdPersonCharacter::DoCrouch);
//ZoomIn : ZoomOut 함수바인딩
InputComponent->BindAction("Zoom", IE_Pressed, this, &AThirdPersonCharacter::ZoomIn);
InputComponent->BindAction("Zoom", IE_Released, this, &AThirdPersonCharacter::ZoomOut);
}
//줌인//
void AThirdPersonCharacter::ZoomIn()
{
bZoomIn = true;
}
///////
//줌아웃//
void AThirdPersonCharacter::ZoomOut()
{
bZoomIn = false;
}
//////////
컴파일 후 HUD와 Widget을 블루플린트를 생성해준다.




블루프린트 생성 후 설정해줌.
PlayerHUD_BP

Player_Crosshair_Widget_BP

크로스헤어 위젯 바인딩을 못찾았다 나오는거는 맨처음에 설정한 UImage와 같은 변수를 생성해줘야한다.

옆에와 같이 UImage를 만들어서 c++클래스에서 선언한 변수명과 똑같이 해줘야 오류가 안생긴다.
이후 디자인그래프에서 자신이 원하는 앵커와 위치를 배치하면 플레이어 화면에서 똑같이 출력된다.

이렇게 나타나고 사라지는걸 확인할수있다.
만약 HUD를 선언을 안할경우에는 HUD에 작성한것을 플레이어 클래스로 옮기면된다.