언리얼 엔진 5/개발 일지

[UE5] 블루아카이브 TPS게임 개발일지 (44) - 피격 방향 표시기 구현 1

ciel45 2024. 1. 20. 12:39

TPS/FPS 게임에는 일반적으로 플레이어가 피격당했을 때, 어느 방향에서 맞았는지 표시해주는 UI가 있다

영어로는 Damage Indicator라고 부른다.

 

이번엔 이를 구현하는 과정을 담을 것이다.

UserWidget을 부모로 하는 블루프린트를 만들어 WBP_DamageIndicator라 짓고, 구글링으로 찾은 적절한 이미지를 가져와 다음과 같이 배치하였다.

부모 클래스 설정
WBP_DamageIndicator

이미지는 화면 중앙을 피봇으로 하여, 빙글빙글 돌아갈 것이다.

 

이번에도 용이한 관리를 위해서, 블루프린트의 부모를 C++클래스로 설정해주려고 한다.

 

 

코드를 살펴보기 전에, 위젯이 페이드아웃되는 애니메이션을 만들어놓을 것이다.

피격을 받고 3초정도 피격을 받지 않으면, 위젯이 천천히 사라지도록 할 것이다.

 

에디터 상단의 Window탭을 열어 Animation 탭을 클릭하여 하단에 표시한 뒤, 새로운 애니메이션을 만들었다.

 

+Animation을 클릭하여 FadeAnim으로 이름짓고,

+ Track을 클릭하고 this를 선택하여 새로운 애니메이션 트랙을 만들고,

만들어진 트랙 우측의 +을 눌러 Render Opacity를 키로 지정해서, 1에서 0으로 0.5초의 시간동안 줄어들도록 하였다.

 

Render Opacity는 위젯의 투명도를 의미한다.

 

이 애니메이션은 C++에서 UPROPERTY(meta = (BindWidget))으로 바인딩하여 사용할 것이다.

 

 

이제 C++ 코드를 살펴보자면 다음과 같다.

 

헤더 파일:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

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

/**
 * 
 */
UCLASS()
class KANNATPS_API UDamageIndicator : public UUserWidget
{
	GENERATED_BODY()
	
public:
	UPROPERTY(BlueprintReadWrite)
	AActor* Causer;

	UPROPERTY(BlueprintReadWrite)
	APawn* KannaCharacter;

	void PlayFadeAnim();

	UFUNCTION()
	void HideWidget();

protected:

	virtual void NativeOnInitialized() override;

	UPROPERTY(BlueprintReadOnly, Transient, meta = (BindWidgetAnim)) // Transient 붙여야함.
	class UWidgetAnimation* FadeAnim;

private:
	FWidgetAnimationDynamicEvent EndDelegate;
};

Causer는 총을 쏜 적, KannaCharacter는 플레이어 자신을 의미한다.

UWidgetAnimation* FadeAnim이 바로 방금 만든 애니메이션과 바인딩시켜줄 변수이다.

EndDelegate는 애니메이션 종료 시 콜백 함수를 달아주기 위한 것으로, 자세한 내용은 후술한다.

 

cpp 파일:

// Fill out your copyright notice in the Description page of Project Settings.


#include "HUD/DamageIndicator.h"

void UDamageIndicator::NativeOnInitialized()
{
	Super::NativeOnInitialized();

	EndDelegate.Clear();
	EndDelegate.BindDynamic(this, &UDamageIndicator::HideWidget);
	BindToAnimationFinished(FadeAnim, EndDelegate);

	KannaCharacter = GetOwningPlayerPawn();
}

void UDamageIndicator::PlayFadeAnim()
{
	PlayAnimation(FadeAnim);
}


void UDamageIndicator::HideWidget()
{
	SetRenderOpacity(0.f);
}

NativeOnInitialized는 위젯이 초기화될 때 딱 한번만 호출되는 함수이므로, 델리게이트에 함수를 바인딩하는 작업 등은 여기서 하기 적절하다.

 

NativeOnConstruct는 위젯을 화면에 나타날 때마다 호출되는 함수로, 여기서 델리게이트 바인딩을 하면 여러번 바인딩될 수 있다. 가급적이면 NativeOnInitialized를 사용해야한다.

 

BindToAnimationFinished를 사용하여 애니메이션이 끝나는 시점에 EndDelegate를 Invoke 시킬 수 있다.

그리고 그 EndDelegate에 바인딩된 함수가 HideWidget이므로, 애니메이션이 끝나면 HideWidget이 호출된다.

 

그 기능은 단지 투명도를 0으로 해놓는 것 뿐이다. 위젯이 페이드아웃된 뒤에는 화면에서 사라져야 하기 때문이다.

 

 

 

위젯을 방향에 따라 돌리고, 화면에 표시하는 부분은 다음 포스팅으로 이어진다.