언리얼5 HUD C++

달봉·2024년 4월 23일

언리얼엔진5

목록 보기
7/12

캐릭터에 총까지 들려줬으니 이제 조준점을 만들어 볼 시간입니다
텍스쳐 객체를 생성하고 직교투영을 ...
은 언리얼에서 해주니깐 유저 인터페이스 위젯을 C++로 제어하는 방법을 알아보겠습니다

UIWidget Blueprint

개인 작업을 해보면서 애니메이션과 UI는 블루프린트에서 생성하고 C++ 로 변수 제어를 하는 방식으로 만들고 있는데
경험해본 바로는 애니메이션 연출 UI 등은 아트팀의 영역이라 코드베이스가 아니라 블루프린트 베이스 작업이 될 가능성이 높기 때문입니다

유니티 환경에서 실무를 했을때도 엔진에서 UI를 전부 세팅한 후 그에 맞는 코드를 생성해 연결하는 방식을 사용했었는데 언리얼에서도 비슷한 방식을 사용할 수 있었습니다

블루 프린트 위젯을 생성해주고..

조준점의 벌어짐을 구현하기 위해 4장의 이미지를 배치했습니다

맨땅에 해딩할때 기능 구현을 위해 책이나 영상 인터넷 등을 참고할 수도 있겠지만 가져다 사용하는것 보다 더 좋은 방법은 역시 직접 알아보는것 입니다 그러기 위해선 블루프린트 내에서 어떤 옵션이 이 객체에 어떤 영향을 미치는지 조작해보면 됩니다

여기선 저 RenderTransform의 Trnasform-Translation의 xy좌표를 움직임으로 제가 원하는 에임 조절이 가능하단걸 알게 됬습니다
여기서 사용한것이 Image 객체였으니 언리얼 내에서 UImage 클래스가 있겠죠?
언리얼 API페이지 가서 찾아봅시다

UImage
찾아보니 예상한대로 UImage 클래스가 존재합니다 그럼 Translation 조절 함수가 있을까요?
UImage 클래스 내에서 선언되있는건 찾을 수 없었습니다
만 이런건 상속된 상위 클래스에 있을 가능성이 있으니 UWidget 까지 확인해보겠습니다

UWidget 클래스 내에서 해당 Translation을 변경해줄것으로 기대되는 함수명을 찾았습니다 이제 만들기만 하면 됩니다

우선 C++로 CrossHair란 클래스를 생성했습니다 그리고 블루프린트로 돌아가서

Graph모드 -> Class Settings -> ClassOptions에서 생성한 C++ 클래스를 부모로 지정합니다

//블루프린트 내의 객체이름을 바탕으로 가져오기
//사실 사용하려는 기능이 UWidget에 있어 UImage로 캐스팅 할 필요는 없습니다
UICross_L = Cast<UImage>(GetWidgetFromName(TEXT("Cross_L")));

CrossHair 클래스에서 위젯 이미지를 바탕으로 객체를 가져와준 후

UICross_L->SetRenderTranslation(FVector2D(-16.f * fAimrate, 0.f));

SetRenderTranslation함수로 이미지 위치를 조절하도록 합니다

	//TSubclassOf<UUserWidget> CrossHairHUDClass
	// 블루프린트 클래스를 받아온다
	static ConstructorHelpers::FClassFinder<UUserWidget> CrossHairHUD(TEXT("/Script/UMGEditor.WidgetBlueprint'/Game/UI/UI_CrossHair.UI_CrossHair_C'"));

	// TSubclassOf 템플릿 클래스 객체에 블루프린트 클래스를 넣어준다
	if (CrossHairHUD.Succeeded())
		CrossHairHUDClass = CrossHairHUD.Class;

원하는 위치에서 위젯클래스 생성 (저는 플레이어 컨트롤러에 생성했습니다)

	if (IsValid(CrossHairHUDClass))
	{
    	// UUserWidget* pCrossHair
		pCrossHair = CreateWidget(GetWorld(), CrossHairHUDClass);

		if (IsValid(pCrossHair))
		{
			// 위젯을 뷰포트에 띄우는 함수
			pCrossHair->AddToViewport();
		}
	}

뷰포트에 추가해줍니다

*뷰포트?

3D좌표가 투영행렬을 거쳐 2D좌표 ( ex: like a 모니터 )로 변환된 공간
직접 텍스쳐를 2D좌표를 그릴땐 직교투영을 통해 다이렉트로 뷰포트 공간으로 보낼 수 있습니다

생성은 됬는데 이제 캐릭터가 저 조준점을 상하 좌우로 벌어지게 만들어야겠죠?

UI에 데이터 전달은 옵저버 패턴을 사용해도 되겠지만 이번에는
유니티 C#에서 보던 delegate action 함수 callback이랑 같은 계열인 언리얼 Delegate를 사용해보겠습니다

//player
//aimrate float값을 보낼 예정이니 OneParam , float 지정
DECLARE_DELEGATE_OneParam(FDele_Player_Aimrate, float);

FDele_Player_Aimrate func_Player_Aimrate;

플레이어에서 Delegate를 만들어 줍니다

void UCrossHair::SetAimRate(float Aimrate)
{
	//에임레이트 변화값 기록
	fTarget_Aimrate = Aimrate;
}

void UCrossHair::BindUserAimRate(ATPSPortfolioCharacter* TPSCharacter)
{
	if(TPSCharacter == nullptr) return;
    //delegate 함수에 CrossHair 함수를 콜백 바인딩
	TPSCharacter->func_Player_Aimrate.BindUObject(this, &UCrossHair::SetAimRate);
}

CrossHair 클래스에서 바인딩 함수를 만들어 주고 float값을 받아줍니다

	if (ATPSPlayerController* TPSController = Cast<ATPSPlayerController>(Controller))
	{
		if (TPSController->pCrossHair != nullptr)
		{
			Cast<UCrossHair>(TPSController->pCrossHair)->BindUserAimRate(this);
		}	
	}

생성 순서를 고려해서 BeginPlay에 컨트롤러에 CrossHair 클래스를 가져와 바인딩 시켜줍니다

func_Player_Aimrate.ExecuteIfBound(fAimrate);

플레이어에서 에임레이트 변화를 줄때 값을 넣어서 Execute로 바인딩된 콜백 함수에 값을 전달합니다

움직임에 반응하는 조준점 완성

profile
개발 블로그

0개의 댓글